/*
 ------------------------------------------------------------------------------
 Copyright (C) 2013 Eternal Games.

 This file is part of the EternalTech source code.

 The EternalTech source code is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or (at your
 option) any later version.

 The EternalTech source code is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 more details.

 You should have received a copy of the GNU General Public License along with
 the EternalTech source code; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ------------------------------------------------------------------------------
*/


//
// sg_light.cpp - light entities and editor management
//


#include "sg_local.h"


enum lightFlags_t {
	LIGHT_START_OFF					= BIT(0)
};


/*
 ==============================================================================

 LIGHT2_SPAWN

 ==============================================================================
*/


/*
 ==================
 SG_Light2_Shown
 ==================
*/
static void SG_Light2_Shown (etEntity *self){

	light_t	*light = (light_t *)self->state.buffer;

	// Update the time offset
	light->materialParms[MATERIALPARM_TIMEOFFSET] = -MS2SEC(level.time);
}

/*
 ==================
 SG_Light2_Trigger
 ==================
*/
static void SG_Light2_Trigger (etEntity *self, etEntity *other, etEntity *activator){

	// Toggle shown/hidden state
	if (self->IsHidden())
		self->Show();
	else
		self->Hide();
}

/*
 ==================
 SG_Light2_Spawn
 ==================
*/
void SG_Light2_Spawn (etEntity *self){

	light_t		*light = (light_t *)self->state.buffer;
	glqBounds	bounds;
	float		ratio;

	// Parse the spawn parameters that will be transmitted to clients
	self->ParseLightState();

	// Get the flags
	if (self->spawnDict.GetBool("startOff"))
		self->spawnFlags |= LIGHT_START_OFF;

	// Finish setting up
	self->flags |= FL_VISIBLE;

	// Set the time offset
	light->materialParms[MATERIALPARM_TIMEOFFSET] = -MS2SEC(level.time);

	// Compute the bounds
	if (light->type != RL_PROJECTED)
		bounds.Set(-light->radius, light->radius);
	else {
		ratio = light->zFar / light->zNear;

		bounds.Clear();

		bounds.AddPoint(glqVec3(-light->xMin, -light->yMin, -light->zNear));
		bounds.AddPoint(glqVec3(-light->xMax, -light->yMin, -light->zNear));
		bounds.AddPoint(glqVec3(-light->xMin, -light->yMax, -light->zNear));
		bounds.AddPoint(glqVec3(-light->xMax, -light->yMax, -light->zNear));
		bounds.AddPoint(glqVec3(-light->xMin * ratio, -light->yMin * ratio, -light->zFar));
		bounds.AddPoint(glqVec3(-light->xMax * ratio, -light->yMin * ratio, -light->zFar));
		bounds.AddPoint(glqVec3(-light->xMin * ratio, -light->yMax * ratio, -light->zFar));
		bounds.AddPoint(glqVec3(-light->xMax * ratio, -light->yMax * ratio, -light->zFar));
	}

	// Set the clip model
	self->SetClipModel(NULL, 0, bounds);

	// Enable physics
	self->EnablePhysics();

	// Set the callback functions
	self->Shown = SG_Light2_Shown;
	self->Trigger = SG_Light2_Trigger;

	// Automatically hide it if needed
	if (self->spawnFlags & LIGHT_START_OFF)
		self->Hide();
	else
		self->Show();
}


/*
 ==============================================================================

 INTEGRATED LIGHT EDITOR

 ==============================================================================
*/

struct lightParms_t {
	char					name[MAX_ENTITY_NAME_LENGTH];

	char					bind[MAX_ENTITY_NAME_LENGTH];
	bool					bindOrientated;

	int						type;

	// Transformation matrix
	glqVec3					origin;
	glqVec3					center;
	glqAngles				angles;

	// Bounding volume for point, cubic, and directional lights
	glqVec3					radius;

	// Frustum definition for projected lights
	float					xMin;
	float					xMax;

	float					yMin;
	float					yMax;

	float					zNear;
	float					zFar;

	// Shadowing parameters
	bool					noShadows;

	float					shadowBias;
	float					shadowSlopeScaleBias;

	float					shadowSoftness;

	// Fogging parameters
	float					fogDistance;
	float					fogHeight;

	// Volumetric lighting parameters
	float					volumeIntensity;

	bool					volumeShadows;
	bool					volumeInteractions;

	// Light attributes
	int						detailLevel;

	glqVec4					color;

	// Server-side parameters
	int						flags;

	// Material
	char					material[MAX_PATH_LENGTH];
};

struct lightEditor_t {
	bool					active;

	etEntity *				focusLight;
	etEntity *				editLight;
};

static lightEditor_t		sg_lightEditor;

static void *				SG_CreateLightEditorWindow ();
static void					SG_DestroyLightEditorWindow ();

static void					SG_EditLightParameters (int index, lightParms_t *parms);


/*
 ==================
 SG_LinkLight
 ==================
*/
static void SG_LinkLight (etEntity *entity){

	light_t		*light = (light_t *)entity->state.buffer;
	glqBounds	bounds;
	float		ratio;

	entity->flags |= FL_VISIBLE;

	entity->SetOrigin(entity->currentOrigin);
	entity->SetAngles(entity->currentAngles);

	// Compute the bounds
	if (light->type != RL_PROJECTED)
		bounds.Set(-light->radius, light->radius);
	else {
		ratio = light->zFar / light->zNear;

		bounds.Clear();

		bounds.AddPoint(glqVec3(-light->xMin, -light->yMin, -light->zNear));
		bounds.AddPoint(glqVec3(-light->xMax, -light->yMin, -light->zNear));
		bounds.AddPoint(glqVec3(-light->xMin, -light->yMax, -light->zNear));
		bounds.AddPoint(glqVec3(-light->xMax, -light->yMax, -light->zNear));
		bounds.AddPoint(glqVec3(-light->xMin * ratio, -light->yMin * ratio, -light->zFar));
		bounds.AddPoint(glqVec3(-light->xMax * ratio, -light->yMin * ratio, -light->zFar));
		bounds.AddPoint(glqVec3(-light->xMin * ratio, -light->yMax * ratio, -light->zFar));
		bounds.AddPoint(glqVec3(-light->xMax * ratio, -light->yMax * ratio, -light->zFar));
	}

	// Set the clip model
	entity->SetClipModel(NULL, 0, bounds);

	// Enable physics
	entity->EnablePhysics();

	// Set the callback functions
	entity->Shown = SG_Light2_Shown;
	entity->Trigger = SG_Light2_Trigger;

	// Show the entity
	entity->Show();
}

/*
 ==================
 SG_UpdateLightSpawnDict
 ==================
*/
static void SG_UpdateLightSpawnDict (etEntity *entity){

	light_t	*light = (light_t *)entity->state.buffer;

	// Clear the editable key/value pairs
	entity->spawnDict.RemoveKeyValue("bind");
	entity->spawnDict.RemoveKeyValue("bindOrientated");
	entity->spawnDict.RemoveKeyValue("type");
	entity->spawnDict.RemoveKeyValue("center");
	entity->spawnDict.RemoveKeyValue("angle");
	entity->spawnDict.RemoveKeyValue("angles");
	entity->spawnDict.RemoveKeyValue("rotation");
	entity->spawnDict.RemoveKeyValue("radius");
	entity->spawnDict.RemoveKeyValue("xMin");
	entity->spawnDict.RemoveKeyValue("xMax");
	entity->spawnDict.RemoveKeyValue("yMin");
	entity->spawnDict.RemoveKeyValue("yMax");
	entity->spawnDict.RemoveKeyValue("zNear");
	entity->spawnDict.RemoveKeyValue("zFar");
	entity->spawnDict.RemoveKeyValue("noShadows");
	entity->spawnDict.RemoveKeyValue("shadowBias");
	entity->spawnDict.RemoveKeyValue("shadowSlopeScaleBias");
	entity->spawnDict.RemoveKeyValue("shadowSoftness");
	entity->spawnDict.RemoveKeyValue("fogDistance");
	entity->spawnDict.RemoveKeyValue("fogHeight");
	entity->spawnDict.RemoveKeyValue("volumeIntensity");
	entity->spawnDict.RemoveKeyValue("volumeShadows");
	entity->spawnDict.RemoveKeyValue("volumeInteractions");
	entity->spawnDict.RemoveKeyValue("detailLevel");
	entity->spawnDict.RemoveKeyValue("startOff");
	entity->spawnDict.RemoveKeyValue("material");
	entity->spawnDict.RemoveKeyValue("color");
	entity->spawnDict.RemoveKeyValue("alpha");
	entity->spawnDict.RemoveKeyValue("materialParm0");
	entity->spawnDict.RemoveKeyValue("materialParm1");
	entity->spawnDict.RemoveKeyValue("materialParm2");
	entity->spawnDict.RemoveKeyValue("materialParm3");

	// Set the editable key/value pairs
	entity->spawnDict.SetString("name", entity->name);
	entity->spawnDict.SetString("className", entity->className);

	if (entity->IsBound()){
		entity->spawnDict.SetString("bind", entity->GetBindMaster()->name);

		if (entity->GetBindOrientated())
			entity->spawnDict.SetBool("bindOrientated", true);
	}

	if (light->type != RL_POINT)
		entity->spawnDict.SetInteger("type", light->type);

	entity->spawnDict.SetVec3("origin", entity->currentOrigin);

	if (!light->center.IsCleared())
		entity->spawnDict.SetVec3("center", light->center);

	if (!entity->currentAngles.IsCleared()){
		if (entity->currentAngles.pitch == 0.0f && entity->currentAngles.roll == 0.0f)
			entity->spawnDict.SetFloat("angle", entity->currentAngles.yaw);
		else
			entity->spawnDict.SetMat3("rotation", entity->currentAxis);
	}

	if (light->radius[0] != 100.0f || light->radius[1] != 100.0f || light->radius[2] != 100.0f)
		entity->spawnDict.SetVec3("radius", light->radius);

	if (light->xMin != -0.5f)
		entity->spawnDict.SetFloat("xMin", light->xMin);

	if (light->xMax != 0.5f)
		entity->spawnDict.SetFloat("xMax", light->xMax);

	if (light->yMin != -0.5f)
		entity->spawnDict.SetFloat("yMin", light->yMin);

	if (light->yMax != 0.5f)
		entity->spawnDict.SetFloat("yMax", light->xMax);

	if (light->zNear != 1.0f)
		entity->spawnDict.SetFloat("zNear", light->zNear);

	if (light->zFar != 200.0f)
		entity->spawnDict.SetFloat("zFar", light->zFar);

	if (light->noShadows)
		entity->spawnDict.SetBool("noShadows", true);

	if (light->shadowBias != 1.0f)
		entity->spawnDict.SetFloat("shadowBias", light->shadowBias);

	if (light->shadowSlopeScaleBias != 1.0f)
		entity->spawnDict.SetFloat("shadowSlopeScaleBias", light->shadowSlopeScaleBias);

	if (light->shadowSoftness != 0.5f)
		entity->spawnDict.SetFloat("shadowSoftness", light->shadowSoftness);

	if (light->fogDistance != 500.0f)
		entity->spawnDict.SetFloat("fogDistance", light->fogDistance);

	if (light->fogHeight != 500.0f)
		entity->spawnDict.SetFloat("fogHeight", light->fogHeight);

	if (light->volumeIntensity)
		entity->spawnDict.SetFloat("volumeIntensity", light->volumeIntensity);

	if (!light->volumeShadows)
		entity->spawnDict.SetBool("volumeShadows", false);

	if (!light->volumeInteractions)
		entity->spawnDict.SetBool("volumeInteractions", false);

	if (light->detailLevel)
		entity->spawnDict.SetInteger("detailLevel", light->detailLevel);

	if (entity->spawnFlags & LIGHT_START_OFF)
		entity->spawnDict.SetBool("startOff", true);

	if (light->material)
		entity->spawnDict.SetString("material", level.configStrings[CS_MATERIALS + light->material]);

	if (entity->baseColor[0] != 1.0f || entity->baseColor[1] != 1.0f || entity->baseColor[2] != 1.0f)
		entity->spawnDict.SetVec3("color", entity->baseColor.ToVec3());

	if (entity->baseColor[3] != 1.0f)
		entity->spawnDict.SetFloat("alpha", entity->baseColor[3]);
}

/*
 ==================
 SG_LightEditorUpdateCallback
 ==================
*/
static void SG_LightEditorUpdateCallback (int index, lightParms_t *parms){

	etEntity	*entity;
	light_t		*light;

	if (!sg_lightEditor.active)
		return;			// Not active

	if (index < MAX_CLIENTS || index >= level.numEntities)
		return;			// Out of range

	entity = &level.entities[index];

	if (!entity->inUse || entity->state.type != ET_LIGHT)
		return;			// Unused or invalid entity

	light = (light_t *)entity->state.buffer;

	// Copy the parameters and clamp as needed
	entity->SetName(SG_ValidateEntityName(parms->name, "light2", index));

	entity->Bind(SG_FindEntity(parms->bind), parms->bindOrientated);

	entity->spawnFlags = parms->flags;
	entity->currentOrigin = parms->origin;
	entity->currentAngles = parms->angles;
	entity->currentAxis = parms->angles.ToMat3();
	entity->baseColor = parms->color;

	light->type = glqMath::ClampInt(parms->type, 0, 3);
	light->center = parms->center;
	light->radius[0] = Max(parms->radius[0], 1.0f);
	light->radius[1] = Max(parms->radius[1], 1.0f);
	light->radius[2] = Max(parms->radius[2], 1.0f);
	light->xMin = parms->xMin;
	light->xMax = parms->xMax;
	light->yMin = parms->yMin;
	light->yMax = parms->yMax;
	light->zNear = Max(parms->zNear, 1.0f);
	light->zFar = Max(parms->zFar, 2.0f);
	light->noShadows = parms->noShadows;
	light->shadowBias = Max(parms->shadowBias, 0.0f);
	light->shadowSlopeScaleBias = Max(parms->shadowSlopeScaleBias, 0.0f);
	light->shadowSoftness = glqMath::ClampFloat(parms->shadowSoftness, 0.0f, 1.0f);
	light->fogDistance = Max(parms->fogDistance, 1.0f);
	light->fogHeight = Max(parms->fogHeight, 1.0f);
	light->volumeIntensity = Max(parms->volumeIntensity, 0.0f);
	light->volumeShadows = parms->volumeShadows;
	light->volumeInteractions = parms->volumeInteractions;
	light->detailLevel = glqMath::ClampInt(parms->detailLevel, 0, 2);
	light->material = SG_MaterialIndex(parms->material);
	light->materialParms[0] = parms->color[0];
	light->materialParms[1] = parms->color[1];
	light->materialParms[2] = parms->color[2];
	light->materialParms[3] = parms->color[3];

	// Validate
	if (light->type == RL_DIRECTIONAL && light->center.IsCleared())
		light->center.Set(0.0f, 0.0f, 1.0f);

	if (light->xMin >= light->xMax){
		light->xMin = -0.5f;
		light->xMax = 0.5f;
	}

	if (light->yMin >= light->yMax){
		light->yMin = -0.5f;
		light->yMax = 0.5f;
	}

	if (light->zNear >= light->zFar){
		light->zNear = 1.0f;
		light->zFar = 200.0f;
	}

	// Update the entity dictionary
	SG_UpdateLightSpawnDict(entity);

	// Link the entity
	SG_LinkLight(entity);
}

/*
 ==================
 SG_LightEditorRemoveCallback
 ==================
*/
static void SG_LightEditorRemoveCallback (int index){

	etEntity	*entity;

	if (!sg_lightEditor.active)
		return;			// Not active

	if (index < MAX_CLIENTS || index >= level.numEntities)
		return;			// Out of range

	entity = &level.entities[index];

	if (!entity->inUse || entity->state.type != ET_LIGHT)
		return;			// Unused or invalid entity

	// Free the entity
	SG_FreeEntity(entity);

	// Force a reset
	sg_lightEditor.focusLight = NULL;
	sg_lightEditor.editLight = NULL;
}

/*
 ==================
 SG_LightEditorSaveCallback
 ==================
*/
static void SG_LightEditorSaveCallback (){

	etEntFile	entFile;
	char		name[MAX_PATH_LENGTH];
	etEntity	*entity;
	int			count;
	int			i;

	if (!sg_lightEditor.active)
		return;			// Not active

	// Write or update the entity file
	Str_SPrintf(name, sizeof(name), "maps/%s.ent2", level.name);

	if (!glqFileSystem->FileExists(name)){
		// Add the new light entities
		count = 0;

		for (i = 0, entity = level.entities; i < level.numEntities; i++, entity++){
			if (!entity->inUse || entity->state.type != ET_LIGHT)
				continue;

			entFile.AddEntity(entity->spawnDict);

			count++;
		}

		// Write it out
		if (entFile.Write(name))
			G_Printf("Wrote %s with %i lights\n", name, count);

		return;
	}

	if (entFile.Parse(name)){
		// Remove all the existing light entities
		entFile.RemoveEntities("light2");

		// Add the new light entities
		count = 0;

		for (i = 0, entity = level.entities; i < level.numEntities; i++, entity++){
			if (!entity->inUse || entity->state.type != ET_LIGHT)
				continue;

			entFile.AddEntity(entity->spawnDict);

			count++;
		}

		// Write it out
		if (entFile.Write(name))
			G_Printf("Wrote %s with %i lights\n", name, count);
	}
}

/*
 ==================
 SG_LightEditorCloseCallback
 ==================
*/
static void SG_LightEditorCloseCallback (){

	if (!sg_lightEditor.active)
		return;			// Not active

	sg_lightEditor.active = false;

	sg_lightEditor.focusLight = NULL;
	sg_lightEditor.editLight = NULL;

	// Close the editor
	glqCommon->CloseEditor();
}

/*
 ==================
 SG_LightEditorMouseEvent
 ==================
*/
static bool SG_LightEditorMouseEvent (){

	etEntity		*entity;
	light_t			*light;
	lightParms_t	parms;

	if (!sg_lightEditor.active)
		return false;	// Not active

	if (!sg_lightEditor.focusLight)
		return false;	// No light has focus

	// Edit the light that has focus
	entity = sg_lightEditor.editLight = sg_lightEditor.focusLight;

	light = (light_t *)entity->state.buffer;

	Str_Copy(parms.name, entity->name, sizeof(parms.name));

	if (!entity->IsBound()){
		Str_Copy(parms.bind, "", sizeof(parms.bind));

		parms.bindOrientated = false;
	}
	else {
		Str_Copy(parms.bind, entity->GetBindMaster()->name, sizeof(parms.bind));

		parms.bindOrientated = entity->GetBindOrientated();
	}

	parms.type = light->type;
	parms.origin = entity->GetOrigin();
	parms.center = light->center;
	parms.angles = entity->GetAngles();
	parms.radius = light->radius;
	parms.xMin = light->xMin;
	parms.xMax = light->xMax;
	parms.yMin = light->yMin;
	parms.yMax = light->yMax;
	parms.zNear = light->zNear;
	parms.zFar = light->zFar;
	parms.noShadows = light->noShadows;
	parms.shadowBias = light->shadowBias;
	parms.shadowSlopeScaleBias = light->shadowSlopeScaleBias;
	parms.shadowSoftness = light->shadowSoftness;
	parms.fogDistance = light->fogDistance;
	parms.fogHeight = light->fogHeight;
	parms.volumeIntensity = light->volumeIntensity;
	parms.volumeShadows = light->volumeShadows;
	parms.volumeInteractions = light->volumeInteractions;
	parms.detailLevel = light->detailLevel;
	parms.color = entity->baseColor;
	parms.flags = entity->spawnFlags;

	if (light->material == 0)
		Str_Copy(parms.material, "", sizeof(parms.material));
	else
		Str_Copy(parms.material, level.configStrings[CS_MATERIALS + light->material], sizeof(parms.material));

	SG_EditLightParameters(entity->state.number, &parms);

	return true;
}

/*
 ==================
 SG_EditLights_f
 ==================
*/
static void SG_EditLights_f (){

	editorCallbacks_t	callbacks;

	// Launch the light editor
	callbacks.createWindow = SG_CreateLightEditorWindow;
	callbacks.destroyWindow = SG_DestroyLightEditorWindow;
	callbacks.mouseEvent = SG_LightEditorMouseEvent;

	if (!glqCommon->LaunchEditor("light", &callbacks))
		return;

	sg_lightEditor.active = true;

	sg_lightEditor.focusLight = NULL;
	sg_lightEditor.editLight = NULL;

	// Finish setting up, but don't edit anything yet
	SG_EditLightParameters(-1, NULL);
}

/*
 ==================
 SG_AddLight_f
 ==================
*/
static void SG_AddLight_f (){

	etEntity		*entity;
	light_t			*light;
	lightParms_t	parms;
	etDict			dict;
	glqVec3			origin;

	if (!sg_lightEditor.active){
		G_Printf("You must launch the light editor to use this command\n");
		return;
	}

	// Add a new light with default parameters in front of the view
	origin = level.localClient->GetViewOrigin() + level.localClient->GetViewAngles().ToForward() * 100.0f;
	origin.Snap();

	dict.SetString("className", "light2");
	dict.SetVec3("origin", origin);

	entity = SG_SpawnEntity(dict);
	if (!entity){
		G_Printf("Couldn't spawn a new light\n");
		return;
	}

	entity->SetMaterialParm(MATERIALPARM_TIMEOFFSET, -MS2SEC(level.time));

	// Edit the new light
	sg_lightEditor.editLight = entity;

	light = (light_t *)entity->state.buffer;

	Str_Copy(parms.name, entity->name, sizeof(parms.name));
	Str_Copy(parms.bind, "", sizeof(parms.bind));
	parms.bindOrientated = false;
	parms.type = light->type;
	parms.origin = entity->currentOrigin;
	parms.center = light->center;
	parms.angles = entity->currentAngles;
	parms.radius = light->radius;
	parms.xMin = light->xMin;
	parms.xMax = light->xMax;
	parms.yMin = light->yMin;
	parms.yMax = light->yMax;
	parms.zNear = light->zNear;
	parms.zFar = light->zFar;
	parms.noShadows = light->noShadows;
	parms.shadowBias = light->shadowBias;
	parms.shadowSlopeScaleBias = light->shadowSlopeScaleBias;
	parms.shadowSoftness = light->shadowSoftness;
	parms.fogDistance = light->fogDistance;
	parms.fogHeight = light->fogHeight;
	parms.volumeIntensity = light->volumeIntensity;
	parms.volumeShadows = light->volumeShadows;
	parms.volumeInteractions = light->volumeInteractions;
	parms.detailLevel = light->detailLevel;
	parms.color = entity->baseColor;
	parms.flags = entity->spawnFlags;

	if (light->material == 0)
		Str_Copy(parms.material, "", sizeof(parms.material));
	else
		Str_Copy(parms.material, level.configStrings[CS_MATERIALS + light->material], sizeof(parms.material));

	SG_EditLightParameters(entity->state.number, &parms);
}

/*
 ==================
 SG_RefreshLightEditor
 ==================
*/
void SG_RefreshLightEditor (){

	etEntity	*visibleEntities[MAX_ENTITIES];
	int			numVisibleEntities;
	etEntity	*entity;
	light_t		*light;
	clipModel_t	*clipModel;
	trace_t		trace;
	char		string[MAX_STRING_LENGTH];
	glqMat3		axis;
	glqVec3		origin;
	glqVec3		forward, up;
	glqVec3		direction;
	float		fraction = 1.0f;
	int			i;

	if (!sg_lightEditor.active)
		return;			// Not active

	sg_lightEditor.focusLight = NULL;

	// Get the current view origin and up vector
	origin = level.localClient->GetViewOrigin();

	level.localClient->GetViewAngles().ToVectors(&forward, NULL, &up);

	// Find visible lights
	numVisibleEntities = 0;

	for (i = 0, entity = level.entities; i < level.numEntities; i++, entity++){
		if (!entity->inUse || entity->state.type != ET_LIGHT)
			continue;

		// Always add the light that is being edited
		if (entity == sg_lightEditor.editLight){
			visibleEntities[numVisibleEntities++] = entity;
			continue;
		}

		// Cull lights by distance
		if (entity->GetOrigin().Distance(origin) > 1000.0f){
			// Check if the view is inside the light bounds. This is so that
			// huge lights are added no matter how far their origin is.
			if (!entity->bounds.ContainsPoint(origin))
				continue;
		}

		// Add it to the list
		visibleEntities[numVisibleEntities++] = entity;
	}

	if (!numVisibleEntities)
		return;		// Nothing more to do here

	// Find the closest light that has focus, if any
	clipModel = glqCollision->SetupBoxModel(CONTENT_SOLID, glqBounds(-5.0f, 5.0f));

	for (i = 0; i < numVisibleEntities; i++){
		entity = visibleEntities[i];

		glqCollision->Trace(origin, origin + forward * MAX_TRACE_DISTANCE, bounds_zero, MASK_SOLID, clipModel, entity->GetOrigin(), entity->GetAngles().ToMat3(), &trace);

		if (trace.fraction < fraction){
			fraction = trace.fraction;

			// This light has focus
			sg_lightEditor.focusLight = entity;
		}
	}

	// Draw all visible lights
	for (i = 0; i < numVisibleEntities; i++){
		entity = visibleEntities[i];
		light = (light_t *)entity->state.buffer;

		origin = entity->GetOrigin();
		axis = entity->GetAngles().ToMat3();

		// Draw a box at the origin
		if (entity != sg_lightEditor.focusLight && entity != sg_lightEditor.editLight)
			glqRenderer->DebugBox(colorWhite, origin, axis, glqBounds(-5.0f, 5.0f), false, VIEW_MAIN);
		else {
			glqRenderer->DebugBox(colorRed, origin, axis, glqBounds(-5.0f, 5.0f), false, VIEW_MAIN);

			if (entity->IsBound())
				glqRenderer->DebugBox(colorRed, entity->currentOrigin, entity->currentAxis, glqBounds(-2.5f, 2.5f), false, VIEW_MAIN);
		}

		// If editing this light
		if (entity == sg_lightEditor.editLight){
			// If a point or cubic light, draw a box at the center
			if (light->type == RL_POINT || light->type == RL_CUBIC){
				glqRenderer->DebugBox(colorRed, axis * light->center + origin, axis, glqBounds(-1.0f, 1.0f), false, VIEW_MAIN);

				if (entity->IsBound())
					glqRenderer->DebugBox(colorRed, entity->currentAxis * light->center + entity->currentOrigin, entity->currentAxis, glqBounds(-0.5f, 0.5f), false, VIEW_MAIN);
			}

			// If a projected light, draw an arrow pointing to the far plane
			if (light->type == RL_PROJECTED){
				glqRenderer->DebugArrow(colorRed, origin, origin - axis[2] * 20.0f, 2.0f, false, VIEW_MAIN);

				if (entity->IsBound())
					glqRenderer->DebugArrow(colorRed, entity->currentOrigin, entity->currentOrigin - entity->currentAxis[2] * 10.0f, 1.0f, false, VIEW_MAIN);
			}

			// If a directional light, draw an arrow pointing in the direction
			// of the light
			if (light->type == RL_DIRECTIONAL){
				if (light->center.IsCleared())
					direction = axis[2];
				else {
					direction = axis * light->center;
					direction.Normalize();
				}

				glqRenderer->DebugArrow(colorRed, origin, origin - direction * 20.0f, 2.0f, false, VIEW_MAIN);

				if (entity->IsBound()){
					if (light->center.IsCleared())
						direction = entity->currentAxis[2];
					else {
						direction = entity->currentAxis * light->center;
						direction.Normalize();
					}

					glqRenderer->DebugArrow(colorRed, entity->currentOrigin, entity->currentOrigin - direction * 10.0f, 1.0f, false, VIEW_MAIN);
				}
			}
		}

		// Draw the entity and material names
		if (light->material == 0)
			Str_SPrintf(string, sizeof(string), "%s", entity->name);
		else
			Str_SPrintf(string, sizeof(string), "%s (%s)", entity->name, level.configStrings[CS_MATERIALS + light->material]);

		glqRenderer->DebugText(colorWhite, true, origin + up * 10.0f, 2.0f, 4.0f, string, false, VIEW_MAIN);
	}
}

/*
 ==================
 SG_CloseLightEditor
 ==================
*/
void SG_CloseLightEditor (){

	SG_LightEditorCloseCallback();
}

/*
 ==================
 SG_InitLightEditor
 ==================
*/
void SG_InitLightEditor (){

	// Add commands
	glqCmdSystem->AddCommand("editLights", SG_EditLights_f, "Launches the integrated light editor", NULL);
	glqCmdSystem->AddCommand("addLight", SG_AddLight_f, "Adds a new light", NULL);
}

/*
 ==================
 SG_ShutdownLightEditor
 ==================
*/
void SG_ShutdownLightEditor (){

	// Remove commands
	glqCmdSystem->RemoveCommand("editLights");
	glqCmdSystem->RemoveCommand("addLight");

	// Close the light editor if active
	if (sg_lightEditor.active)
		glqCommon->CloseEditor();

	glqMemory->Fill(&sg_lightEditor, 0, sizeof(lightEditor_t));
}


/*
 ==============================================================================

 PLATFORM SPECIFIC EDITOR FUNCTIONS

 ==============================================================================
*/


#ifdef _WIN32

#define LIGHT_EDITOR_WINDOW_NAME		GAME_NAME " Light Editor"
#define LIGHT_EDITOR_WINDOW_CLASS		GAME_NAME " Light Editor"
#define LIGHT_EDITOR_WINDOW_STYLE		(WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX)

#define LIGHT_COLOR_BITMAP_SIZE			(80 * 20)

static lightParms_t			sg_lightParms = {"light", "", false, RL_POINT, glqVec3(0.0f), glqVec3(0.0f), glqAngles(0.0f), glqVec3(100.0f), -0.5f, 0.5f, -0.5f, 0.5f, 1.0f, 200.0f, false, 1.0f, 1.0f, 0.5f, 500.0f, 500.0f, 0.0f, true, true, 0, glqVec4(1.0f), 0, "_defaultLight"};

struct lightParmsEditor_t {
	bool					initialized;
	bool					enabled;

	int						editIndex;
	lightParms_t			editParms;

	dword					bitmapBits[LIGHT_COLOR_BITMAP_SIZE];

	// Window stuff
	HINSTANCE				hInstance;

	HWND					hWnd;
	HWND					hWndName;
	HWND					hWndNameValue;
	HWND					hWndBindTo;
	HWND					hWndBindToValue;
	HWND					hWndBindOrientated;
	HWND					hWndFrame1;
	HWND					hWndFrame2;
	HWND					hWndFrame3;
	HWND					hWndFrame4;
	HWND					hWndX;
	HWND					hWndY;
	HWND					hWndZ;
	HWND					hWndOrigin;
	HWND					hWndOriginXValue;
	HWND					hWndOriginXSpin;
	HWND					hWndOriginYValue;
	HWND					hWndOriginYSpin;
	HWND					hWndOriginZValue;
	HWND					hWndOriginZSpin;
	HWND					hWndCenter;
	HWND					hWndCenterXValue;
	HWND					hWndCenterXSpin;
	HWND					hWndCenterYValue;
	HWND					hWndCenterYSpin;
	HWND					hWndCenterZValue;
	HWND					hWndCenterZSpin;
	HWND					hWndAngles;
	HWND					hWndAnglesXValue;
	HWND					hWndAnglesXSpin;
	HWND					hWndAnglesYValue;
	HWND					hWndAnglesYSpin;
	HWND					hWndAnglesZValue;
	HWND					hWndAnglesZSpin;
	HWND					hWndStartOff;
	HWND					hWndType;
	HWND					hWndTypeValue;
	HWND					hWndRadiusX;
	HWND					hWndRadiusY;
	HWND					hWndRadiusZ;
	HWND					hWndRadius;
	HWND					hWndRadiusXValue;
	HWND					hWndRadiusXSpin;
	HWND					hWndRadiusYValue;
	HWND					hWndRadiusYSpin;
	HWND					hWndRadiusZValue;
	HWND					hWndRadiusZSpin;
	HWND					hWndFrustumX;
	HWND					hWndFrustumY;
	HWND					hWndFrustumZ;
	HWND					hWndFrustumMin;
	HWND					hWndFrustumMax;
	HWND					hWndXMinValue;
	HWND					hWndXMinSpin;
	HWND					hWndXMaxValue;
	HWND					hWndXMaxSpin;
	HWND					hWndYMinValue;
	HWND					hWndYMinSpin;
	HWND					hWndYMaxValue;
	HWND					hWndYMaxSpin;
	HWND					hWndZNearValue;
	HWND					hWndZNearSpin;
	HWND					hWndZFarValue;
	HWND					hWndZFarSpin;
	HWND					hWndCastShadows;
	HWND					hWndShadowBias;
	HWND					hWndShadowBiasValue;
	HWND					hWndShadowBiasSpin;
	HWND					hWndShadowSlopeScaleBias;
	HWND					hWndShadowSlopeScaleBiasValue;
	HWND					hWndShadowSlopeScaleBiasSpin;
	HWND					hWndShadowSoftness;
	HWND					hWndShadowSoftnessValue;
	HWND					hWndShadowSoftnessSpin;
	HWND					hWndFogDistance;
	HWND					hWndFogDistanceValue;
	HWND					hWndFogDistanceSpin;
	HWND					hWndFogHeight;
	HWND					hWndFogHeightValue;
	HWND					hWndFogHeightSpin;
	HWND					hWndVolumeIntensity;
	HWND					hWndVolumeIntensityValue;
	HWND					hWndVolumeIntensitySpin;
	HWND					hWndVolumeShadows;
	HWND					hWndVolumeShadowsValue;
	HWND					hWndVolumeInteractions;
	HWND					hWndVolumeInteractionsValue;
	HWND					hWndDetailLevel;
	HWND					hWndDetailLevelValue;
	HWND					hWndColor;
	HWND					hWndColorValue;
	HWND					hWndAlpha;
	HWND					hWndAlphaValue;
	HWND					hWndAlphaSpin;
	HWND					hWndMaterial;
	HWND					hWndMaterialValue;
	HWND					hWndApply;
	HWND					hWndReset;
	HWND					hWndDefaults;
	HWND					hWndRemove;
	HWND					hWndSave;

	HFONT					hFont;

	HBITMAP					hBitmap;

	COLORREF				crCurrent;
	COLORREF				crCustom[16];
};

static lightParmsEditor_t	sg_lightParmsEditor;


/*
 ==================
 SG_AddLightMaterial
 ==================
*/
static void SG_AddLightMaterial (const char *name){

	if (Str_ICompareChars(name, "lights/", 7))
		return;

	if (SendMessage(sg_lightParmsEditor.hWndMaterialValue, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)name) != CB_ERR)
		return;

	SendMessage(sg_lightParmsEditor.hWndMaterialValue, CB_ADDSTRING, 0, (LPARAM)name);
}

/*
 ==================
 SG_ApplyLightParameters
 ==================
*/
static void SG_ApplyLightParameters (){

	lightParms_t	parms;
	char			string[64];
	int				index;

	if (!sg_lightParmsEditor.enabled)
		return;

	// Read the controls
	if (GetWindowText(sg_lightParmsEditor.hWndNameValue, string, sizeof(string)))
		Str_Copy(parms.name, SG_ValidateEntityName(string, "light", sg_lightParmsEditor.editIndex), sizeof(parms.name));
	else
		Str_Copy(parms.name, SG_ValidateEntityName(NULL, "light", sg_lightParmsEditor.editIndex), sizeof(parms.name));

	index = SendMessage(sg_lightParmsEditor.hWndBindToValue, CB_GETCURSEL, 0, 0);
	if (index == CB_ERR)
		Str_Copy(parms.bind, "", sizeof(parms.bind));
	else
		SendMessage(sg_lightParmsEditor.hWndBindToValue, CB_GETLBTEXT, (WPARAM)index, (LPARAM)parms.bind);

	if (SendMessage(sg_lightParmsEditor.hWndBindOrientated, BM_GETCHECK, 0, 0) == BST_CHECKED)
		parms.bindOrientated = true;
	else
		parms.bindOrientated = false;

	if (GetWindowText(sg_lightParmsEditor.hWndOriginXValue, string, sizeof(string)))
		parms.origin[0] = Str_ToFloat(string);
	else
		parms.origin[0] = sg_lightParmsEditor.editParms.origin[0];

	if (GetWindowText(sg_lightParmsEditor.hWndOriginYValue, string, sizeof(string)))
		parms.origin[1] = Str_ToFloat(string);
	else
		parms.origin[1] = sg_lightParmsEditor.editParms.origin[1];

	if (GetWindowText(sg_lightParmsEditor.hWndOriginZValue, string, sizeof(string)))
		parms.origin[2] = Str_ToFloat(string);
	else
		parms.origin[2] = sg_lightParmsEditor.editParms.origin[2];

	if (GetWindowText(sg_lightParmsEditor.hWndCenterXValue, string, sizeof(string)))
		parms.center[0] = Str_ToFloat(string);
	else
		parms.center[0] = sg_lightParmsEditor.editParms.center[0];

	if (GetWindowText(sg_lightParmsEditor.hWndCenterYValue, string, sizeof(string)))
		parms.center[1] = Str_ToFloat(string);
	else
		parms.center[1] = sg_lightParmsEditor.editParms.center[1];

	if (GetWindowText(sg_lightParmsEditor.hWndCenterZValue, string, sizeof(string)))
		parms.center[2] = Str_ToFloat(string);
	else
		parms.center[2] = sg_lightParmsEditor.editParms.center[2];

	if (GetWindowText(sg_lightParmsEditor.hWndAnglesXValue, string, sizeof(string)))
		parms.angles[0] = Str_ToFloat(string);
	else
		parms.angles[0] = sg_lightParmsEditor.editParms.angles[0];

	if (GetWindowText(sg_lightParmsEditor.hWndAnglesYValue, string, sizeof(string)))
		parms.angles[1] = Str_ToFloat(string);
	else
		parms.angles[1] = sg_lightParmsEditor.editParms.angles[1];

	if (GetWindowText(sg_lightParmsEditor.hWndAnglesZValue, string, sizeof(string)))
		parms.angles[2] = Str_ToFloat(string);
	else
		parms.angles[2] = sg_lightParmsEditor.editParms.angles[2];

	parms.flags = 0;

	if (SendMessage(sg_lightParmsEditor.hWndStartOff, BM_GETCHECK, 0, 0) == BST_CHECKED)
		parms.flags |= LIGHT_START_OFF;

	parms.type = SendMessage(sg_lightParmsEditor.hWndTypeValue, CB_GETCURSEL, 0, 0);

	if (parms.type != RL_PROJECTED){
		if (GetWindowText(sg_lightParmsEditor.hWndRadiusXValue, string, sizeof(string)))
			parms.radius[0] = Str_ToFloat(string);
		else
			parms.radius[0] = sg_lightParmsEditor.editParms.radius[0];

		if (GetWindowText(sg_lightParmsEditor.hWndRadiusYValue, string, sizeof(string)))
			parms.radius[1] = Str_ToFloat(string);
		else
			parms.radius[1] = sg_lightParmsEditor.editParms.radius[1];

		if (GetWindowText(sg_lightParmsEditor.hWndRadiusZValue, string, sizeof(string)))
			parms.radius[2] = Str_ToFloat(string);
		else
			parms.radius[2] = sg_lightParmsEditor.editParms.radius[2];

		parms.xMin = -0.5f;
		parms.xMax = 0.5f;

		parms.yMin = -0.5f;
		parms.yMax = 0.5f;

		parms.zNear = 1.0f;
		parms.zFar = 200.0f;
	}
	else {
		if (GetWindowText(sg_lightParmsEditor.hWndXMinValue, string, sizeof(string)))
			parms.xMin = Str_ToFloat(string);
		else
			parms.xMin = sg_lightParmsEditor.editParms.xMin;

		if (GetWindowText(sg_lightParmsEditor.hWndXMaxValue, string, sizeof(string)))
			parms.xMax = Str_ToFloat(string);
		else
			parms.xMax = sg_lightParmsEditor.editParms.xMax;

		if (GetWindowText(sg_lightParmsEditor.hWndYMinValue, string, sizeof(string)))
			parms.yMin = Str_ToFloat(string);
		else
			parms.yMin = sg_lightParmsEditor.editParms.yMin;

		if (GetWindowText(sg_lightParmsEditor.hWndYMaxValue, string, sizeof(string)))
			parms.yMax = Str_ToFloat(string);
		else
			parms.yMax = sg_lightParmsEditor.editParms.yMax;

		if (GetWindowText(sg_lightParmsEditor.hWndZNearValue, string, sizeof(string)))
			parms.zNear = Str_ToFloat(string);
		else
			parms.zNear = sg_lightParmsEditor.editParms.zNear;

		if (GetWindowText(sg_lightParmsEditor.hWndZFarValue, string, sizeof(string)))
			parms.zFar = Str_ToFloat(string);
		else
			parms.zFar = sg_lightParmsEditor.editParms.zFar;

		parms.radius.Set(100.0f);
	}

	if (SendMessage(sg_lightParmsEditor.hWndCastShadows, BM_GETCHECK, 0, 0) == BST_UNCHECKED){
		parms.noShadows = true;

		parms.shadowBias = 1.0f;
		parms.shadowSlopeScaleBias = 1.0f;

		parms.shadowSoftness = 0.5f;
	}
	else {
		parms.noShadows = false;

		if (GetWindowText(sg_lightParmsEditor.hWndShadowBiasValue, string, sizeof(string)))
			parms.shadowBias = Str_ToFloat(string);
		else
			parms.shadowBias = sg_lightParmsEditor.editParms.shadowBias;

		if (GetWindowText(sg_lightParmsEditor.hWndShadowSlopeScaleBiasValue, string, sizeof(string)))
			parms.shadowSlopeScaleBias = Str_ToFloat(string);
		else
			parms.shadowSlopeScaleBias = sg_lightParmsEditor.editParms.shadowSlopeScaleBias;

		if (GetWindowText(sg_lightParmsEditor.hWndShadowSoftnessValue, string, sizeof(string)))
			parms.shadowSoftness = Str_ToFloat(string);
		else
			parms.shadowSoftness = sg_lightParmsEditor.editParms.shadowSoftness;
	}

	if (GetWindowText(sg_lightParmsEditor.hWndFogDistanceValue, string, sizeof(string)))
		parms.fogDistance = Str_ToFloat(string);
	else
		parms.fogDistance = sg_lightParmsEditor.editParms.fogDistance;

	if (GetWindowText(sg_lightParmsEditor.hWndFogHeightValue, string, sizeof(string)))
		parms.fogHeight = Str_ToFloat(string);
	else
		parms.fogHeight = sg_lightParmsEditor.editParms.fogHeight;

	if (GetWindowText(sg_lightParmsEditor.hWndVolumeIntensityValue, string, sizeof(string)))
		parms.volumeIntensity = Str_ToFloat(string);
	else
		parms.volumeIntensity = sg_lightParmsEditor.editParms.volumeIntensity;

	if (!SendMessage(sg_lightParmsEditor.hWndVolumeShadowsValue, CB_GETCURSEL, 0, 0))
		parms.volumeShadows = true;
	else
		parms.volumeShadows = false;

	if (!SendMessage(sg_lightParmsEditor.hWndVolumeInteractionsValue, CB_GETCURSEL, 0, 0))
		parms.volumeInteractions = true;
	else
		parms.volumeInteractions = false;

	parms.detailLevel = SendMessage(sg_lightParmsEditor.hWndDetailLevelValue, CB_GETCURSEL, 0, 0);
	if (parms.detailLevel < 0 || parms.detailLevel > 2)
		parms.detailLevel = sg_lightParmsEditor.editParms.detailLevel;

	parms.color[0] = GetRValue(sg_lightParmsEditor.crCurrent) * (1.0f / 255.0f);
	parms.color[1] = GetGValue(sg_lightParmsEditor.crCurrent) * (1.0f / 255.0f);
	parms.color[2] = GetBValue(sg_lightParmsEditor.crCurrent) * (1.0f / 255.0f);

	if (GetWindowText(sg_lightParmsEditor.hWndAlphaValue, string, sizeof(string)))
		parms.color[3] = Str_ToFloat(string);
	else
		parms.color[3] = sg_lightParmsEditor.editParms.color[3];

	if (!GetWindowText(sg_lightParmsEditor.hWndMaterialValue, parms.material, sizeof(parms.material)))
		Str_Copy(parms.material, "", sizeof(parms.material));

	// Update the parameters
	SG_LightEditorUpdateCallback(sg_lightParmsEditor.editIndex, &parms);
}

/*
 ==================
 SG_ResetLightParameters
 ==================
*/
static void SG_ResetLightParameters (lightParms_t *parms){

	etEntity	*master;
	byte		r, g, b;
	int			index;
	int			i;

	if (!sg_lightParmsEditor.enabled)
		return;

	// Update the controls
	SetWindowText(sg_lightParmsEditor.hWndNameValue, parms->name);

	index = SendMessage(sg_lightParmsEditor.hWndBindToValue, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)parms->bind);
	if (index == CB_ERR)
		SendMessage(sg_lightParmsEditor.hWndBindToValue, CB_SETCURSEL, (WPARAM)0, 0);
	else
		SendMessage(sg_lightParmsEditor.hWndBindToValue, CB_SETCURSEL, (WPARAM)index, 0);

	if (parms->bindOrientated)
		SendMessage(sg_lightParmsEditor.hWndBindOrientated, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
	else
		SendMessage(sg_lightParmsEditor.hWndBindOrientated, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);

	master = SG_FindEntity(parms->bind);

	SetWindowText(sg_lightParmsEditor.hWndOriginXValue, Str_FromFloat(parms->origin[0], -1));
	SetWindowText(sg_lightParmsEditor.hWndOriginYValue, Str_FromFloat(parms->origin[1], -1));
	SetWindowText(sg_lightParmsEditor.hWndOriginZValue, Str_FromFloat(parms->origin[2], -1));

	SetWindowText(sg_lightParmsEditor.hWndCenterXValue, Str_FromFloat(parms->center[0], -1));
	SetWindowText(sg_lightParmsEditor.hWndCenterYValue, Str_FromFloat(parms->center[1], -1));
	SetWindowText(sg_lightParmsEditor.hWndCenterZValue, Str_FromFloat(parms->center[2], -1));

	SetWindowText(sg_lightParmsEditor.hWndAnglesXValue, Str_FromFloat(parms->angles[0], -1));
	SetWindowText(sg_lightParmsEditor.hWndAnglesYValue, Str_FromFloat(parms->angles[1], -1));
	SetWindowText(sg_lightParmsEditor.hWndAnglesZValue, Str_FromFloat(parms->angles[2], -1));

	if (parms->flags & LIGHT_START_OFF)
		SendMessage(sg_lightParmsEditor.hWndStartOff, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
	else
		SendMessage(sg_lightParmsEditor.hWndStartOff, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);

	SendMessage(sg_lightParmsEditor.hWndTypeValue, CB_SETCURSEL, (WPARAM)glqMath::ClampInt(parms->type, 0, 3), 0);

	SetWindowText(sg_lightParmsEditor.hWndRadiusXValue, Str_FromFloat(parms->radius[0], -1));
	SetWindowText(sg_lightParmsEditor.hWndRadiusYValue, Str_FromFloat(parms->radius[1], -1));
	SetWindowText(sg_lightParmsEditor.hWndRadiusZValue, Str_FromFloat(parms->radius[2], -1));

	SetWindowText(sg_lightParmsEditor.hWndXMinValue, Str_FromFloat(parms->xMin, -1));
	SetWindowText(sg_lightParmsEditor.hWndXMaxValue, Str_FromFloat(parms->xMax, -1));

	SetWindowText(sg_lightParmsEditor.hWndYMinValue, Str_FromFloat(parms->yMin, -1));
	SetWindowText(sg_lightParmsEditor.hWndYMaxValue, Str_FromFloat(parms->yMax, -1));

	SetWindowText(sg_lightParmsEditor.hWndZNearValue, Str_FromFloat(parms->zNear, -1));
	SetWindowText(sg_lightParmsEditor.hWndZFarValue, Str_FromFloat(parms->zFar, -1));

	if (parms->noShadows)
		SendMessage(sg_lightParmsEditor.hWndCastShadows, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
	else
		SendMessage(sg_lightParmsEditor.hWndCastShadows, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);

	SetWindowText(sg_lightParmsEditor.hWndShadowBiasValue, Str_FromFloat(parms->shadowBias, -1));
	SetWindowText(sg_lightParmsEditor.hWndShadowSlopeScaleBiasValue, Str_FromFloat(parms->shadowSlopeScaleBias, -1));

	SetWindowText(sg_lightParmsEditor.hWndShadowSoftnessValue, Str_FromFloat(parms->shadowSoftness, -1));

	SetWindowText(sg_lightParmsEditor.hWndFogDistanceValue, Str_FromFloat(parms->fogDistance, -1));
	SetWindowText(sg_lightParmsEditor.hWndFogHeightValue, Str_FromFloat(parms->fogHeight, -1));

	SetWindowText(sg_lightParmsEditor.hWndVolumeIntensityValue, Str_FromFloat(parms->volumeIntensity, -1));

	SendMessage(sg_lightParmsEditor.hWndVolumeShadowsValue, CB_SETCURSEL, (WPARAM)(!parms->volumeShadows), 0);
	SendMessage(sg_lightParmsEditor.hWndVolumeInteractionsValue, CB_SETCURSEL, (WPARAM)(!parms->volumeInteractions), 0);

	SendMessage(sg_lightParmsEditor.hWndDetailLevelValue, CB_SETCURSEL, (WPARAM)glqMath::ClampInt(parms->detailLevel, 0, 2), 0);

	r = glqMath::FloatToByte(parms->color[0] * 255.0f);
	g = glqMath::FloatToByte(parms->color[1] * 255.0f);
	b = glqMath::FloatToByte(parms->color[2] * 255.0f);

	sg_lightParmsEditor.crCurrent = RGB(r, g, b);

	for (i = 0; i < LIGHT_COLOR_BITMAP_SIZE; i++)
		sg_lightParmsEditor.bitmapBits[i] = (b << 0) | (g << 8) | (r << 16) | (255 << 24);

	SetBitmapBits(sg_lightParmsEditor.hBitmap, LIGHT_COLOR_BITMAP_SIZE * 4, sg_lightParmsEditor.bitmapBits);
	SendMessage(sg_lightParmsEditor.hWndColorValue, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)sg_lightParmsEditor.hBitmap);

	SetWindowText(sg_lightParmsEditor.hWndAlphaValue, Str_FromFloat(glqMath::ClampFloat(parms->color[3], 0.0f, 1.0f), -1));

	SetWindowText(sg_lightParmsEditor.hWndMaterialValue, parms->material);

	// Enable or disable the controls
	EnableWindow(sg_lightParmsEditor.hWndBindOrientated, (master != NULL));

	if (parms->type != RL_PROJECTED){
		EnableWindow(sg_lightParmsEditor.hWndRadiusX, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndRadiusY, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndRadiusZ, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndRadius, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndRadiusXValue, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndRadiusXSpin, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndRadiusYValue, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndRadiusYSpin, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndRadiusZValue, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndRadiusZSpin, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndFrustumX, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndFrustumY, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndFrustumZ, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndFrustumMin, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndFrustumMax, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndXMinValue, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndXMinSpin, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndXMaxValue, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndXMaxSpin, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndYMinValue, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndYMinSpin, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndYMaxValue, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndYMaxSpin, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndZNearValue, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndZNearSpin, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndZFarValue, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndZFarSpin, FALSE);
	}
	else {
		EnableWindow(sg_lightParmsEditor.hWndRadiusX, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndRadiusY, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndRadiusZ, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndRadius, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndRadiusXValue, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndRadiusXSpin, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndRadiusYValue, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndRadiusYSpin, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndRadiusZValue, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndRadiusZSpin, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndFrustumX, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndFrustumY, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndFrustumZ, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndFrustumMin, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndFrustumMax, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndXMinValue, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndXMinSpin, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndXMaxValue, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndXMaxSpin, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndYMinValue, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndYMinSpin, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndYMaxValue, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndYMaxSpin, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndZNearValue, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndZNearSpin, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndZFarValue, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndZFarSpin, TRUE);
	}

	if (parms->noShadows){
		EnableWindow(sg_lightParmsEditor.hWndShadowBias, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndShadowBiasValue, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndShadowBiasSpin, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndShadowSlopeScaleBias, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndShadowSlopeScaleBiasValue, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndShadowSlopeScaleBiasSpin, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndShadowSoftness, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndShadowSoftnessValue, FALSE);
		EnableWindow(sg_lightParmsEditor.hWndShadowSoftnessSpin, FALSE);
	}
	else {
		EnableWindow(sg_lightParmsEditor.hWndShadowBias, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndShadowBiasValue, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndShadowBiasSpin, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndShadowSlopeScaleBias, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndShadowSlopeScaleBiasValue, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndShadowSlopeScaleBiasSpin, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndShadowSoftness, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndShadowSoftnessValue, TRUE);
		EnableWindow(sg_lightParmsEditor.hWndShadowSoftnessSpin, TRUE);
	}

	// Update the parameters
	SG_LightEditorUpdateCallback(sg_lightParmsEditor.editIndex, parms);
}

/*
 ==================
 SG_RemoveLightParameters
 ==================
*/
static void SG_RemoveLightParameters (){

	etEntity	*master;
	byte		r, g, b;
	int			index;
	int			i;

	if (!sg_lightParmsEditor.enabled)
		return;

	sg_lightParmsEditor.enabled = false;

	// Update the controls
	SetWindowText(sg_lightParmsEditor.hWndNameValue, sg_lightParms.name);

	index = SendMessage(sg_lightParmsEditor.hWndBindToValue, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)sg_lightParms.bind);
	if (index == CB_ERR)
		SendMessage(sg_lightParmsEditor.hWndBindToValue, CB_SETCURSEL, (WPARAM)0, 0);
	else
		SendMessage(sg_lightParmsEditor.hWndBindToValue, CB_SETCURSEL, (WPARAM)index, 0);

	master = SG_FindEntity(sg_lightParms.bind);

	if (sg_lightParms.bindOrientated)
		SendMessage(sg_lightParmsEditor.hWndBindOrientated, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
	else
		SendMessage(sg_lightParmsEditor.hWndBindOrientated, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);

	SetWindowText(sg_lightParmsEditor.hWndOriginXValue, Str_FromFloat(sg_lightParms.origin[0], -1));
	SetWindowText(sg_lightParmsEditor.hWndOriginYValue, Str_FromFloat(sg_lightParms.origin[1], -1));
	SetWindowText(sg_lightParmsEditor.hWndOriginZValue, Str_FromFloat(sg_lightParms.origin[2], -1));

	SetWindowText(sg_lightParmsEditor.hWndCenterXValue, Str_FromFloat(sg_lightParms.center[0], -1));
	SetWindowText(sg_lightParmsEditor.hWndCenterYValue, Str_FromFloat(sg_lightParms.center[1], -1));
	SetWindowText(sg_lightParmsEditor.hWndCenterZValue, Str_FromFloat(sg_lightParms.center[2], -1));

	SetWindowText(sg_lightParmsEditor.hWndAnglesXValue, Str_FromFloat(sg_lightParms.angles[0], -1));
	SetWindowText(sg_lightParmsEditor.hWndAnglesYValue, Str_FromFloat(sg_lightParms.angles[1], -1));
	SetWindowText(sg_lightParmsEditor.hWndAnglesZValue, Str_FromFloat(sg_lightParms.angles[2], -1));

	if (sg_lightParms.flags & LIGHT_START_OFF)
		SendMessage(sg_lightParmsEditor.hWndStartOff, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
	else
		SendMessage(sg_lightParmsEditor.hWndStartOff, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);

	SendMessage(sg_lightParmsEditor.hWndTypeValue, CB_SETCURSEL, (WPARAM)glqMath::ClampInt(sg_lightParms.type, 0, 3), 0);

	SetWindowText(sg_lightParmsEditor.hWndRadiusXValue, Str_FromFloat(sg_lightParms.radius[0], -1));
	SetWindowText(sg_lightParmsEditor.hWndRadiusYValue, Str_FromFloat(sg_lightParms.radius[1], -1));
	SetWindowText(sg_lightParmsEditor.hWndRadiusZValue, Str_FromFloat(sg_lightParms.radius[2], -1));

	SetWindowText(sg_lightParmsEditor.hWndXMinValue, Str_FromFloat(sg_lightParms.xMin, -1));
	SetWindowText(sg_lightParmsEditor.hWndXMaxValue, Str_FromFloat(sg_lightParms.xMax, -1));

	SetWindowText(sg_lightParmsEditor.hWndYMinValue, Str_FromFloat(sg_lightParms.yMin, -1));
	SetWindowText(sg_lightParmsEditor.hWndYMaxValue, Str_FromFloat(sg_lightParms.yMax, -1));

	SetWindowText(sg_lightParmsEditor.hWndZNearValue, Str_FromFloat(sg_lightParms.zNear, -1));
	SetWindowText(sg_lightParmsEditor.hWndZFarValue, Str_FromFloat(sg_lightParms.zFar, -1));

	if (sg_lightParms.noShadows)
		SendMessage(sg_lightParmsEditor.hWndCastShadows, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
	else
		SendMessage(sg_lightParmsEditor.hWndCastShadows, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);

	SetWindowText(sg_lightParmsEditor.hWndShadowBiasValue, Str_FromFloat(sg_lightParms.shadowBias, -1));
	SetWindowText(sg_lightParmsEditor.hWndShadowSlopeScaleBiasValue, Str_FromFloat(sg_lightParms.shadowSlopeScaleBias, -1));

	SetWindowText(sg_lightParmsEditor.hWndShadowSoftnessValue, Str_FromFloat(sg_lightParms.shadowSoftness, -1));

	SetWindowText(sg_lightParmsEditor.hWndFogDistanceValue, Str_FromFloat(sg_lightParms.fogDistance, -1));
	SetWindowText(sg_lightParmsEditor.hWndFogHeightValue, Str_FromFloat(sg_lightParms.fogHeight, -1));

	SetWindowText(sg_lightParmsEditor.hWndVolumeIntensityValue, Str_FromFloat(sg_lightParms.volumeIntensity, -1));

	SendMessage(sg_lightParmsEditor.hWndVolumeShadowsValue, CB_SETCURSEL, (WPARAM)(!sg_lightParms.volumeShadows), 0);
	SendMessage(sg_lightParmsEditor.hWndVolumeInteractionsValue, CB_SETCURSEL, (WPARAM)(!sg_lightParms.volumeInteractions), 0);

	SendMessage(sg_lightParmsEditor.hWndDetailLevelValue, CB_SETCURSEL, (WPARAM)glqMath::ClampInt(sg_lightParms.detailLevel, 0, 2), 0);

	r = glqMath::FloatToByte(sg_lightParms.color[0] * 255.0f);
	g = glqMath::FloatToByte(sg_lightParms.color[1] * 255.0f);
	b = glqMath::FloatToByte(sg_lightParms.color[2] * 255.0f);

	sg_lightParmsEditor.crCurrent = RGB(r, g, b);

	for (i = 0; i < LIGHT_COLOR_BITMAP_SIZE; i++)
		sg_lightParmsEditor.bitmapBits[i] = (b << 0) | (g << 8) | (r << 16) | (255 << 24);

	SetBitmapBits(sg_lightParmsEditor.hBitmap, LIGHT_COLOR_BITMAP_SIZE * 4, sg_lightParmsEditor.bitmapBits);
	SendMessage(sg_lightParmsEditor.hWndColorValue, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)sg_lightParmsEditor.hBitmap);

	SetWindowText(sg_lightParmsEditor.hWndAlphaValue, Str_FromFloat(glqMath::ClampFloat(sg_lightParms.color[3], 0.0f, 1.0f), -1));

	SetWindowText(sg_lightParmsEditor.hWndMaterialValue, sg_lightParms.material);

	// Disable the controls
	EnableWindow(sg_lightParmsEditor.hWndName, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndNameValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndBindTo, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndBindToValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndBindOrientated, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndFrame1, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndFrame2, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndFrame3, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndFrame4, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndX, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndY, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndZ, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndOrigin, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndOriginXValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndOriginXSpin, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndOriginYValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndOriginYSpin, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndOriginZValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndOriginZSpin, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndCenter, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndCenterXValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndCenterXSpin, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndCenterYValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndCenterYSpin, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndCenterZValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndCenterZSpin, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndAngles, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndAnglesXValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndAnglesXSpin, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndAnglesYValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndAnglesYSpin, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndAnglesZValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndAnglesZSpin, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndStartOff, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndType, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndTypeValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndRadiusX, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndRadiusY, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndRadiusZ, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndRadius, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndRadiusXValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndRadiusXSpin, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndRadiusYValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndRadiusYSpin, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndRadiusZValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndRadiusZSpin, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndFrustumX, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndFrustumY, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndFrustumZ, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndFrustumMin, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndFrustumMax, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndXMinValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndXMinSpin, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndXMaxValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndXMaxSpin, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndYMinValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndYMinSpin, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndYMaxValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndYMaxSpin, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndZNearValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndZNearSpin, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndZFarValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndZFarSpin, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndCastShadows, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndShadowBias, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndShadowBiasValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndShadowBiasSpin, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndShadowSlopeScaleBias, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndShadowSlopeScaleBiasValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndShadowSlopeScaleBiasSpin, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndShadowSoftness, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndShadowSoftnessValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndShadowSoftnessSpin, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndFogDistance, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndFogDistanceValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndFogDistanceSpin, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndFogHeight, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndFogHeightValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndFogHeightSpin, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndVolumeIntensity, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndVolumeIntensityValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndVolumeIntensitySpin, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndVolumeShadows, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndVolumeShadowsValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndVolumeInteractions, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndVolumeInteractionsValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndDetailLevel, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndDetailLevelValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndColor, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndColorValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndAlpha, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndAlphaValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndAlphaSpin, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndMaterial, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndMaterialValue, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndApply, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndReset, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndDefaults, FALSE);
	EnableWindow(sg_lightParmsEditor.hWndRemove, FALSE);

	// Remove the parameters
	SG_LightEditorRemoveCallback(sg_lightParmsEditor.editIndex);
}

/*
 ==================
 SG_LightEditorWindowProc
 ==================
*/
static LRESULT CALLBACK SG_LightEditorWindowProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){

	CHOOSECOLOR	chooseColor;
	etEntity	*master;
	char		string[64];
	int			result;
	int			i;

	switch (uMsg){
	case WM_CLOSE:
		SG_ApplyLightParameters();

		SG_LightEditorCloseCallback();

		break;
	case WM_SYSCOMMAND:
		if (wParam == SC_KEYMENU)
			return 0;

		break;
	case WM_COMMAND:
		if (HIWORD(wParam) == EN_KILLFOCUS){
			if ((HWND)lParam == sg_lightParmsEditor.hWndNameValue){
				if (!sg_lightParmsEditor.enabled)
					break;

				GetWindowText(sg_lightParmsEditor.hWndNameValue, string, sizeof(string));
				SetWindowText(sg_lightParmsEditor.hWndNameValue, SG_ValidateEntityName(string, "light", sg_lightParmsEditor.editIndex));

				break;
			}
		}

		if (HIWORD(wParam) == BN_CLICKED){
			if ((HWND)lParam == sg_lightParmsEditor.hWndBindOrientated){
				SG_ApplyLightParameters();
				break;
			}

			if ((HWND)lParam == sg_lightParmsEditor.hWndCastShadows){
				if (SendMessage(sg_lightParmsEditor.hWndCastShadows, BM_GETCHECK, 0, 0) == BST_UNCHECKED){
					EnableWindow(sg_lightParmsEditor.hWndShadowBias, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndShadowBiasValue, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndShadowBiasSpin, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndShadowSlopeScaleBias, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndShadowSlopeScaleBiasValue, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndShadowSlopeScaleBiasSpin, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndShadowSoftness, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndShadowSoftnessValue, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndShadowSoftnessSpin, FALSE);
				}
				else {
					EnableWindow(sg_lightParmsEditor.hWndShadowBias, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndShadowBiasValue, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndShadowBiasSpin, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndShadowSlopeScaleBias, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndShadowSlopeScaleBiasValue, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndShadowSlopeScaleBiasSpin, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndShadowSoftness, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndShadowSoftnessValue, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndShadowSoftnessSpin, TRUE);
				}

				SG_ApplyLightParameters();

				break;
			}

			if ((HWND)lParam == sg_lightParmsEditor.hWndColorValue){
				chooseColor.lStructSize = sizeof(CHOOSECOLOR);
				chooseColor.hwndOwner = sg_lightParmsEditor.hWnd;
				chooseColor.hInstance = NULL;
				chooseColor.rgbResult = sg_lightParmsEditor.crCurrent;
				chooseColor.lpCustColors = sg_lightParmsEditor.crCustom;
				chooseColor.Flags = CC_FULLOPEN | CC_RGBINIT;
				chooseColor.lCustData = 0;
				chooseColor.lpfnHook = NULL;
				chooseColor.lpTemplateName = NULL;

				if (ChooseColor(&chooseColor)){
					sg_lightParmsEditor.crCurrent = chooseColor.rgbResult;

					for (i = 0; i < LIGHT_COLOR_BITMAP_SIZE; i++)
						sg_lightParmsEditor.bitmapBits[i] = (GetBValue(chooseColor.rgbResult) << 0) | (GetGValue(chooseColor.rgbResult) << 8) | (GetRValue(chooseColor.rgbResult) << 16) | (255 << 24);

					SetBitmapBits(sg_lightParmsEditor.hBitmap, LIGHT_COLOR_BITMAP_SIZE * 4, sg_lightParmsEditor.bitmapBits);
					SendMessage(sg_lightParmsEditor.hWndColorValue, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)sg_lightParmsEditor.hBitmap);

					SG_ApplyLightParameters();
				}

				break;
			}

			if ((HWND)lParam == sg_lightParmsEditor.hWndApply){
				SG_ApplyLightParameters();
				break;
			}

			if ((HWND)lParam == sg_lightParmsEditor.hWndReset){
				SG_ResetLightParameters(&sg_lightParmsEditor.editParms);
				break;
			}

			if ((HWND)lParam == sg_lightParmsEditor.hWndDefaults){
				SG_ResetLightParameters(&sg_lightParms);
				break;
			}

			if ((HWND)lParam == sg_lightParmsEditor.hWndRemove){
				SG_RemoveLightParameters();
				break;
			}

			if ((HWND)lParam == sg_lightParmsEditor.hWndSave){
				SG_ApplyLightParameters();

				SG_LightEditorSaveCallback();

				break;
			}
		}

		if (HIWORD(wParam) == CBN_SELCHANGE){
			if ((HWND)lParam == sg_lightParmsEditor.hWndBindToValue){
				result = SendMessage(sg_lightParmsEditor.hWndBindToValue, CB_GETCURSEL, 0, 0);

				if (result == CB_ERR){
					SG_ApplyLightParameters();
					break;
				}

				SendMessage(sg_lightParmsEditor.hWndBindToValue, CB_GETLBTEXT, (WPARAM)result, (LPARAM)string);

				master = SG_FindEntity(string);

				EnableWindow(sg_lightParmsEditor.hWndBindOrientated, (master != NULL));

				SG_ApplyLightParameters();

				break;
			}

			if ((HWND)lParam == sg_lightParmsEditor.hWndTypeValue){
				result = SendMessage(sg_lightParmsEditor.hWndTypeValue, CB_GETCURSEL, 0, 0);

				if (result < 0 || result > 3)
					break;

				if (result != RL_PROJECTED){
					EnableWindow(sg_lightParmsEditor.hWndRadiusX, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndRadiusY, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndRadiusZ, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndRadius, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndRadiusXValue, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndRadiusXSpin, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndRadiusYValue, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndRadiusYSpin, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndRadiusZValue, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndRadiusZSpin, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndFrustumX, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndFrustumY, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndFrustumZ, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndFrustumMin, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndFrustumMax, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndXMinValue, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndXMinSpin, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndXMaxValue, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndXMaxSpin, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndYMinValue, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndYMinSpin, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndYMaxValue, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndYMaxSpin, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndZNearValue, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndZNearSpin, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndZFarValue, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndZFarSpin, FALSE);
				}
				else {
					EnableWindow(sg_lightParmsEditor.hWndRadiusX, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndRadiusY, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndRadiusZ, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndRadius, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndRadiusXValue, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndRadiusXSpin, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndRadiusYValue, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndRadiusYSpin, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndRadiusZValue, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndRadiusZSpin, FALSE);
					EnableWindow(sg_lightParmsEditor.hWndFrustumX, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndFrustumY, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndFrustumZ, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndFrustumMin, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndFrustumMax, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndXMinValue, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndXMinSpin, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndXMaxValue, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndXMaxSpin, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndYMinValue, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndYMinSpin, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndYMaxValue, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndYMaxSpin, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndZNearValue, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndZNearSpin, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndZFarValue, TRUE);
					EnableWindow(sg_lightParmsEditor.hWndZFarSpin, TRUE);
				}

				SG_ApplyLightParameters();

				break;
			}

			if ((HWND)lParam == sg_lightParmsEditor.hWndVolumeShadowsValue){
				SG_ApplyLightParameters();
				break;
			}

			if ((HWND)lParam == sg_lightParmsEditor.hWndVolumeInteractionsValue){
				SG_ApplyLightParameters();
				break;
			}

			if ((HWND)lParam == sg_lightParmsEditor.hWndDetailLevelValue){
				SG_ApplyLightParameters();
				break;
			}
		}

		break;
	case WM_NOTIFY:
		if (((LPNMHDR)lParam)->code == UDN_DELTAPOS){
			if (((LPNMHDR)lParam)->hwndFrom == sg_lightParmsEditor.hWndOriginXSpin){
				GetWindowText(sg_lightParmsEditor.hWndOriginXValue, string, sizeof(string));

				if (((LPNMUPDOWN)lParam)->iDelta < 0)
					SetWindowText(sg_lightParmsEditor.hWndOriginXValue, Str_FromFloat(Str_ToFloat(string) + 1.0f, -1));
				else
					SetWindowText(sg_lightParmsEditor.hWndOriginXValue, Str_FromFloat(Str_ToFloat(string) - 1.0f, -1));

				SG_ApplyLightParameters();

				break;
			}

			if (((LPNMHDR)lParam)->hwndFrom == sg_lightParmsEditor.hWndOriginYSpin){
				GetWindowText(sg_lightParmsEditor.hWndOriginYValue, string, sizeof(string));

				if (((LPNMUPDOWN)lParam)->iDelta < 0)
					SetWindowText(sg_lightParmsEditor.hWndOriginYValue, Str_FromFloat(Str_ToFloat(string) + 1.0f, -1));
				else
					SetWindowText(sg_lightParmsEditor.hWndOriginYValue, Str_FromFloat(Str_ToFloat(string) - 1.0f, -1));

				SG_ApplyLightParameters();

				break;
			}

			if (((LPNMHDR)lParam)->hwndFrom == sg_lightParmsEditor.hWndOriginZSpin){
				GetWindowText(sg_lightParmsEditor.hWndOriginZValue, string, sizeof(string));

				if (((LPNMUPDOWN)lParam)->iDelta < 0)
					SetWindowText(sg_lightParmsEditor.hWndOriginZValue, Str_FromFloat(Str_ToFloat(string) + 1.0f, -1));
				else
					SetWindowText(sg_lightParmsEditor.hWndOriginZValue, Str_FromFloat(Str_ToFloat(string) - 1.0f, -1));

				SG_ApplyLightParameters();

				break;
			}

			if (((LPNMHDR)lParam)->hwndFrom == sg_lightParmsEditor.hWndCenterXSpin){
				GetWindowText(sg_lightParmsEditor.hWndCenterXValue, string, sizeof(string));

				if (((LPNMUPDOWN)lParam)->iDelta < 0)
					SetWindowText(sg_lightParmsEditor.hWndCenterXValue, Str_FromFloat(Str_ToFloat(string) + 1.0f, -1));
				else
					SetWindowText(sg_lightParmsEditor.hWndCenterXValue, Str_FromFloat(Str_ToFloat(string) - 1.0f, -1));

				SG_ApplyLightParameters();

				break;
			}

			if (((LPNMHDR)lParam)->hwndFrom == sg_lightParmsEditor.hWndCenterYSpin){
				GetWindowText(sg_lightParmsEditor.hWndCenterYValue, string, sizeof(string));

				if (((LPNMUPDOWN)lParam)->iDelta < 0)
					SetWindowText(sg_lightParmsEditor.hWndCenterYValue, Str_FromFloat(Str_ToFloat(string) + 1.0f, -1));
				else
					SetWindowText(sg_lightParmsEditor.hWndCenterYValue, Str_FromFloat(Str_ToFloat(string) - 1.0f, -1));

				SG_ApplyLightParameters();

				break;
			}

			if (((LPNMHDR)lParam)->hwndFrom == sg_lightParmsEditor.hWndCenterZSpin){
				GetWindowText(sg_lightParmsEditor.hWndCenterZValue, string, sizeof(string));

				if (((LPNMUPDOWN)lParam)->iDelta < 0)
					SetWindowText(sg_lightParmsEditor.hWndCenterZValue, Str_FromFloat(Str_ToFloat(string) + 1.0f, -1));
				else
					SetWindowText(sg_lightParmsEditor.hWndCenterZValue, Str_FromFloat(Str_ToFloat(string) - 1.0f, -1));

				SG_ApplyLightParameters();

				break;
			}

			if (((LPNMHDR)lParam)->hwndFrom == sg_lightParmsEditor.hWndAnglesXSpin){
				GetWindowText(sg_lightParmsEditor.hWndAnglesXValue, string, sizeof(string));

				if (((LPNMUPDOWN)lParam)->iDelta < 0)
					SetWindowText(sg_lightParmsEditor.hWndAnglesXValue, Str_FromFloat(Str_ToFloat(string) + 1.0f, -1));
				else
					SetWindowText(sg_lightParmsEditor.hWndAnglesXValue, Str_FromFloat(Str_ToFloat(string) - 1.0f, -1));

				SG_ApplyLightParameters();

				break;
			}

			if (((LPNMHDR)lParam)->hwndFrom == sg_lightParmsEditor.hWndAnglesYSpin){
				GetWindowText(sg_lightParmsEditor.hWndAnglesYValue, string, sizeof(string));

				if (((LPNMUPDOWN)lParam)->iDelta < 0)
					SetWindowText(sg_lightParmsEditor.hWndAnglesYValue, Str_FromFloat(Str_ToFloat(string) + 1.0f, -1));
				else
					SetWindowText(sg_lightParmsEditor.hWndAnglesYValue, Str_FromFloat(Str_ToFloat(string) - 1.0f, -1));

				SG_ApplyLightParameters();

				break;
			}

			if (((LPNMHDR)lParam)->hwndFrom == sg_lightParmsEditor.hWndAnglesZSpin){
				GetWindowText(sg_lightParmsEditor.hWndAnglesZValue, string, sizeof(string));

				if (((LPNMUPDOWN)lParam)->iDelta < 0)
					SetWindowText(sg_lightParmsEditor.hWndAnglesZValue, Str_FromFloat(Str_ToFloat(string) + 1.0f, -1));
				else
					SetWindowText(sg_lightParmsEditor.hWndAnglesZValue, Str_FromFloat(Str_ToFloat(string) - 1.0f, -1));

				SG_ApplyLightParameters();

				break;
			}

			if (((LPNMHDR)lParam)->hwndFrom == sg_lightParmsEditor.hWndRadiusXSpin){
				GetWindowText(sg_lightParmsEditor.hWndRadiusXValue, string, sizeof(string));

				if (((LPNMUPDOWN)lParam)->iDelta < 0)
					SetWindowText(sg_lightParmsEditor.hWndRadiusXValue, Str_FromFloat(Max(Str_ToFloat(string) + 1.0f, 1.0f), -1));
				else
					SetWindowText(sg_lightParmsEditor.hWndRadiusXValue, Str_FromFloat(Max(Str_ToFloat(string) - 1.0f, 1.0f), -1));

				SG_ApplyLightParameters();

				break;
			}

			if (((LPNMHDR)lParam)->hwndFrom == sg_lightParmsEditor.hWndRadiusYSpin){
				GetWindowText(sg_lightParmsEditor.hWndRadiusYValue, string, sizeof(string));

				if (((LPNMUPDOWN)lParam)->iDelta < 0)
					SetWindowText(sg_lightParmsEditor.hWndRadiusYValue, Str_FromFloat(Max(Str_ToFloat(string) + 1.0f, 1.0f), -1));
				else
					SetWindowText(sg_lightParmsEditor.hWndRadiusYValue, Str_FromFloat(Max(Str_ToFloat(string) - 1.0f, 1.0f), -1));

				SG_ApplyLightParameters();

				break;
			}

			if (((LPNMHDR)lParam)->hwndFrom == sg_lightParmsEditor.hWndRadiusZSpin){
				GetWindowText(sg_lightParmsEditor.hWndRadiusZValue, string, sizeof(string));

				if (((LPNMUPDOWN)lParam)->iDelta < 0)
					SetWindowText(sg_lightParmsEditor.hWndRadiusZValue, Str_FromFloat(Max(Str_ToFloat(string) + 1.0f, 1.0f), -1));
				else
					SetWindowText(sg_lightParmsEditor.hWndRadiusZValue, Str_FromFloat(Max(Str_ToFloat(string) - 1.0f, 1.0f), -1));

				SG_ApplyLightParameters();

				break;
			}

			if (((LPNMHDR)lParam)->hwndFrom == sg_lightParmsEditor.hWndXMinSpin){
				GetWindowText(sg_lightParmsEditor.hWndXMinValue, string, sizeof(string));

				if (((LPNMUPDOWN)lParam)->iDelta < 0)
					SetWindowText(sg_lightParmsEditor.hWndXMinValue, Str_FromFloat(Str_ToFloat(string) + 0.1f, -1));
				else
					SetWindowText(sg_lightParmsEditor.hWndXMinValue, Str_FromFloat(Str_ToFloat(string) - 0.1f, -1));

				SG_ApplyLightParameters();

				break;
			}

			if (((LPNMHDR)lParam)->hwndFrom == sg_lightParmsEditor.hWndXMaxSpin){
				GetWindowText(sg_lightParmsEditor.hWndXMaxValue, string, sizeof(string));

				if (((LPNMUPDOWN)lParam)->iDelta < 0)
					SetWindowText(sg_lightParmsEditor.hWndXMaxValue, Str_FromFloat(Str_ToFloat(string) + 0.1f, -1));
				else
					SetWindowText(sg_lightParmsEditor.hWndXMaxValue, Str_FromFloat(Str_ToFloat(string) - 0.1f, -1));

				SG_ApplyLightParameters();

				break;
			}

			if (((LPNMHDR)lParam)->hwndFrom == sg_lightParmsEditor.hWndYMinSpin){
				GetWindowText(sg_lightParmsEditor.hWndYMinValue, string, sizeof(string));

				if (((LPNMUPDOWN)lParam)->iDelta < 0)
					SetWindowText(sg_lightParmsEditor.hWndYMinValue, Str_FromFloat(Str_ToFloat(string) + 0.1f, -1));
				else
					SetWindowText(sg_lightParmsEditor.hWndYMinValue, Str_FromFloat(Str_ToFloat(string) - 0.1f, -1));

				SG_ApplyLightParameters();

				break;
			}

			if (((LPNMHDR)lParam)->hwndFrom == sg_lightParmsEditor.hWndYMaxSpin){
				GetWindowText(sg_lightParmsEditor.hWndYMaxValue, string, sizeof(string));

				if (((LPNMUPDOWN)lParam)->iDelta < 0)
					SetWindowText(sg_lightParmsEditor.hWndYMaxValue, Str_FromFloat(Str_ToFloat(string) + 0.1f, -1));
				else
					SetWindowText(sg_lightParmsEditor.hWndYMaxValue, Str_FromFloat(Str_ToFloat(string) - 0.1f, -1));

				SG_ApplyLightParameters();

				break;
			}

			if (((LPNMHDR)lParam)->hwndFrom == sg_lightParmsEditor.hWndZNearSpin){
				GetWindowText(sg_lightParmsEditor.hWndZNearValue, string, sizeof(string));

				if (((LPNMUPDOWN)lParam)->iDelta < 0)
					SetWindowText(sg_lightParmsEditor.hWndZNearValue, Str_FromFloat(Max(Str_ToFloat(string) + 1.0f, 1.0f), -1));
				else
					SetWindowText(sg_lightParmsEditor.hWndZNearValue, Str_FromFloat(Max(Str_ToFloat(string) - 1.0f, 1.0f), -1));

				SG_ApplyLightParameters();

				break;
			}

			if (((LPNMHDR)lParam)->hwndFrom == sg_lightParmsEditor.hWndZFarSpin){
				GetWindowText(sg_lightParmsEditor.hWndZFarValue, string, sizeof(string));

				if (((LPNMUPDOWN)lParam)->iDelta < 0)
					SetWindowText(sg_lightParmsEditor.hWndZFarValue, Str_FromFloat(Max(Str_ToFloat(string) + 1.0f, 2.0f), -1));
				else
					SetWindowText(sg_lightParmsEditor.hWndZFarValue, Str_FromFloat(Max(Str_ToFloat(string) - 1.0f, 2.0f), -1));

				SG_ApplyLightParameters();

				break;
			}

			if (((LPNMHDR)lParam)->hwndFrom == sg_lightParmsEditor.hWndShadowBiasSpin){
				GetWindowText(sg_lightParmsEditor.hWndShadowBiasValue, string, sizeof(string));

				if (((LPNMUPDOWN)lParam)->iDelta < 0)
					SetWindowText(sg_lightParmsEditor.hWndShadowBiasValue, Str_FromFloat(Max(Str_ToFloat(string) + 0.1f, 0.0f), -1));
				else
					SetWindowText(sg_lightParmsEditor.hWndShadowBiasValue, Str_FromFloat(Max(Str_ToFloat(string) - 0.1f, 0.0f), -1));

				SG_ApplyLightParameters();

				break;
			}

			if (((LPNMHDR)lParam)->hwndFrom == sg_lightParmsEditor.hWndShadowSlopeScaleBiasSpin){
				GetWindowText(sg_lightParmsEditor.hWndShadowSlopeScaleBiasValue, string, sizeof(string));

				if (((LPNMUPDOWN)lParam)->iDelta < 0)
					SetWindowText(sg_lightParmsEditor.hWndShadowSlopeScaleBiasValue, Str_FromFloat(Max(Str_ToFloat(string) + 0.1f, 0.0f), -1));
				else
					SetWindowText(sg_lightParmsEditor.hWndShadowSlopeScaleBiasValue, Str_FromFloat(Max(Str_ToFloat(string) - 0.1f, 0.0f), -1));

				SG_ApplyLightParameters();

				break;
			}

			if (((LPNMHDR)lParam)->hwndFrom == sg_lightParmsEditor.hWndShadowSoftnessSpin){
				GetWindowText(sg_lightParmsEditor.hWndShadowSoftnessValue, string, sizeof(string));

				if (((LPNMUPDOWN)lParam)->iDelta < 0)
					SetWindowText(sg_lightParmsEditor.hWndShadowSoftnessValue, Str_FromFloat(glqMath::ClampFloat(Str_ToFloat(string) + 0.01f, 0.0f, 1.0f), -1));
				else
					SetWindowText(sg_lightParmsEditor.hWndShadowSoftnessValue, Str_FromFloat(glqMath::ClampFloat(Str_ToFloat(string) - 0.01f, 0.0f, 1.0f), -1));

				SG_ApplyLightParameters();

				break;
			}

			if (((LPNMHDR)lParam)->hwndFrom == sg_lightParmsEditor.hWndFogDistanceSpin){
				GetWindowText(sg_lightParmsEditor.hWndFogDistanceValue, string, sizeof(string));

				if (((LPNMUPDOWN)lParam)->iDelta < 0)
					SetWindowText(sg_lightParmsEditor.hWndFogDistanceValue, Str_FromFloat(Max(Str_ToFloat(string) + 1.0f, 1.0f), -1));
				else
					SetWindowText(sg_lightParmsEditor.hWndFogDistanceValue, Str_FromFloat(Max(Str_ToFloat(string) - 1.0f, 1.0f), -1));

				SG_ApplyLightParameters();

				break;
			}

			if (((LPNMHDR)lParam)->hwndFrom == sg_lightParmsEditor.hWndFogHeightSpin){
				GetWindowText(sg_lightParmsEditor.hWndFogHeightValue, string, sizeof(string));

				if (((LPNMUPDOWN)lParam)->iDelta < 0)
					SetWindowText(sg_lightParmsEditor.hWndFogHeightValue, Str_FromFloat(Max(Str_ToFloat(string) + 1.0f, 1.0f), -1));
				else
					SetWindowText(sg_lightParmsEditor.hWndFogHeightValue, Str_FromFloat(Max(Str_ToFloat(string) - 1.0f, 1.0f), -1));

				SG_ApplyLightParameters();

				break;
			}

			if (((LPNMHDR)lParam)->hwndFrom == sg_lightParmsEditor.hWndVolumeIntensitySpin){
				GetWindowText(sg_lightParmsEditor.hWndVolumeIntensityValue, string, sizeof(string));

				if (((LPNMUPDOWN)lParam)->iDelta < 0)
					SetWindowText(sg_lightParmsEditor.hWndVolumeIntensityValue, Str_FromFloat(Max(Str_ToFloat(string) + 0.01f, 0.0f), -1));
				else
					SetWindowText(sg_lightParmsEditor.hWndVolumeIntensityValue, Str_FromFloat(Max(Str_ToFloat(string) - 0.01f, 0.0f), -1));

				SG_ApplyLightParameters();

				break;
			}

			if (((LPNMHDR)lParam)->hwndFrom == sg_lightParmsEditor.hWndAlphaSpin){
				GetWindowText(sg_lightParmsEditor.hWndAlphaValue, string, sizeof(string));

				if (((LPNMUPDOWN)lParam)->iDelta < 0)
					SetWindowText(sg_lightParmsEditor.hWndAlphaValue, Str_FromFloat(glqMath::ClampFloat(Str_ToFloat(string) + 0.01f, 0.0f, 1.0f), -1));
				else
					SetWindowText(sg_lightParmsEditor.hWndAlphaValue, Str_FromFloat(glqMath::ClampFloat(Str_ToFloat(string) - 0.01f, 0.0f, 1.0f), -1));

				SG_ApplyLightParameters();

				break;
			}
		}

		break;
	}

	// Pass all unhandled messages to DefWindowProc
	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

/*
 ==================
 SG_CreateLightEditorWindow
 ==================
*/
static void *SG_CreateLightEditorWindow (){

	INITCOMMONCONTROLSEX	initCommonControls;
	WNDCLASSEX				wndClass;
	RECT					rect;
	HDC						hDC;
	int						screenWidth, screenHeight;
	int						x, y, w, h;
	int						size;
	int						i;

	// Get the instance handle
	sg_lightParmsEditor.hInstance = (HINSTANCE)glqSystem->GetInstanceHandle();

	// Initialize up-down control class
	initCommonControls.dwSize = sizeof(INITCOMMONCONTROLSEX);
	initCommonControls.dwICC = ICC_UPDOWN_CLASS;

	InitCommonControlsEx(&initCommonControls);

	// Calculate window position and dimensions
	screenWidth = GetSystemMetrics(SM_CXSCREEN);
	screenHeight = GetSystemMetrics(SM_CYSCREEN);
	
	rect.left = (screenWidth - 566) / 2;
	rect.top = (screenHeight - 554) / 2;
	rect.right = rect.left + 566;
	rect.bottom = rect.top + 554;

	AdjustWindowRectEx(&rect, LIGHT_EDITOR_WINDOW_STYLE, FALSE, 0);
	
	x = rect.left;
	y = rect.top;
	w = rect.right - rect.left;
	h = rect.bottom - rect.top;

	// Register the window class
	wndClass.cbSize = sizeof(WNDCLASSEX);
	wndClass.style = 0;
	wndClass.lpfnWndProc = SG_LightEditorWindowProc;
	wndClass.cbClsExtra = 0;
	wndClass.cbWndExtra = 0;
	wndClass.hInstance = (HINSTANCE)glqSystem->GetInstanceHandle();
	wndClass.hIcon = (HICON)glqSystem->GetIconHandle();
	wndClass.hIconSm = NULL;
	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
	wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
	wndClass.lpszMenuName = NULL;
	wndClass.lpszClassName = LIGHT_EDITOR_WINDOW_CLASS;

	if (!RegisterClassEx(&wndClass)){
		G_Printf(S_COLOR_RED "Could not register light editor window class\n");

		return NULL;
	}

	// Create the window
	sg_lightParmsEditor.hWnd = CreateWindowEx(0, LIGHT_EDITOR_WINDOW_CLASS, LIGHT_EDITOR_WINDOW_NAME, LIGHT_EDITOR_WINDOW_STYLE, x, y, w, h, NULL, NULL, sg_lightParmsEditor.hInstance, NULL);
	if (!sg_lightParmsEditor.hWnd){
		UnregisterClass(LIGHT_EDITOR_WINDOW_CLASS, sg_lightParmsEditor.hInstance);

		G_Printf(S_COLOR_RED "Could not create light editor window\n");

		return NULL;
	}

	// Create the controls
	sg_lightParmsEditor.hWndName = CreateWindowEx(0, "STATIC", "Name", WS_CHILD | WS_VISIBLE | SS_LEFT, 8, 12, 180, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndNameValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 8, 26, 180, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndBindTo = CreateWindowEx(0, "STATIC", "Bind to", WS_CHILD | WS_VISIBLE | SS_RIGHT, 314, 16, 60, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndBindToValue = CreateWindowEx(WS_EX_CLIENTEDGE, "COMBOBOX", NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP | CBS_DROPDOWNLIST | CBS_SORT, 378, 12, 180, 200, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndBindOrientated = CreateWindowEx(0, "BUTTON", "Bind orientated", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_AUTOCHECKBOX, 378, 60, 180, 16, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndFrame1 = CreateWindowEx(0, "BUTTON", NULL, WS_CHILD | WS_VISIBLE | BS_GROUPBOX, 8, 84, 310, 94, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndFrame2 = CreateWindowEx(0, "BUTTON", NULL, WS_CHILD | WS_VISIBLE | BS_GROUPBOX, 8, 184, 310, 272, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndFrame3 = CreateWindowEx(0, "BUTTON", NULL, WS_CHILD | WS_VISIBLE | BS_GROUPBOX, 326, 84, 232, 372, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndFrame4 = CreateWindowEx(0, "BUTTON", NULL, WS_CHILD | WS_VISIBLE | BS_GROUPBOX, 8, 464, 550, 36, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndX = CreateWindowEx(0, "STATIC", "X", WS_CHILD | WS_VISIBLE | SS_CENTER, 66, 92, 80, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndY = CreateWindowEx(0, "STATIC", "Y", WS_CHILD | WS_VISIBLE | SS_CENTER, 150, 92, 80, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndZ = CreateWindowEx(0, "STATIC", "Z", WS_CHILD | WS_VISIBLE | SS_CENTER, 234, 92, 80, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndOrigin = CreateWindowEx(0, "STATIC", "Origin", WS_CHILD | WS_VISIBLE | SS_RIGHT, 12, 109, 50, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndOriginXValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_RIGHT | ES_AUTOHSCROLL, 66, 106, 80, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndOriginXSpin = CreateWindowEx(0, UPDOWN_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_AUTOBUDDY, 126, 106, 20, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndOriginYValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_RIGHT | ES_AUTOHSCROLL, 150, 106, 80, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndOriginYSpin = CreateWindowEx(0, UPDOWN_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_AUTOBUDDY, 210, 106, 20, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndOriginZValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_RIGHT | ES_AUTOHSCROLL, 234, 106, 80, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndOriginZSpin = CreateWindowEx(0, UPDOWN_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_AUTOBUDDY, 294, 106, 20, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndCenter = CreateWindowEx(0, "STATIC", "Center", WS_CHILD | WS_VISIBLE | SS_RIGHT, 12, 133, 50, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndCenterXValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_RIGHT | ES_AUTOHSCROLL, 66, 130, 80, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndCenterXSpin = CreateWindowEx(0, UPDOWN_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_AUTOBUDDY, 126, 130, 20, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndCenterYValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_RIGHT | ES_AUTOHSCROLL, 150, 130, 80, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndCenterYSpin = CreateWindowEx(0, UPDOWN_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_AUTOBUDDY, 210, 130, 20, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndCenterZValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_RIGHT | ES_AUTOHSCROLL, 234, 130, 80, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndCenterZSpin = CreateWindowEx(0, UPDOWN_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_AUTOBUDDY, 294, 130, 20, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndAngles = CreateWindowEx(0, "STATIC", "Angles", WS_CHILD | WS_VISIBLE | SS_RIGHT, 12, 157, 50, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndAnglesXValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_RIGHT | ES_AUTOHSCROLL, 66, 154, 80, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndAnglesXSpin = CreateWindowEx(0, UPDOWN_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_AUTOBUDDY, 126, 154, 20, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndAnglesYValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_RIGHT | ES_AUTOHSCROLL, 150, 154, 80, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndAnglesYSpin = CreateWindowEx(0, UPDOWN_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_AUTOBUDDY, 210, 154, 20, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndAnglesZValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_RIGHT | ES_AUTOHSCROLL, 234, 154, 80, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndAnglesZSpin = CreateWindowEx(0, UPDOWN_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_AUTOBUDDY, 294, 154, 20, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndStartOff = CreateWindowEx(0, "BUTTON", "Start off", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_AUTOCHECKBOX, 12, 197, 134, 16, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndType = CreateWindowEx(0, "STATIC", "Type", WS_CHILD | WS_VISIBLE | SS_RIGHT, 150, 198, 80, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndTypeValue = CreateWindowEx(WS_EX_CLIENTEDGE, "COMBOBOX", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | CBS_DROPDOWNLIST, 234, 194, 80, 200, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndRadiusX = CreateWindowEx(0, "STATIC", "X", WS_CHILD | WS_VISIBLE | SS_CENTER, 66, 250, 80, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndRadiusY = CreateWindowEx(0, "STATIC", "Y", WS_CHILD | WS_VISIBLE | SS_CENTER, 150, 250, 80, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndRadiusZ = CreateWindowEx(0, "STATIC", "Z", WS_CHILD | WS_VISIBLE | SS_CENTER, 234, 250, 80, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndRadius = CreateWindowEx(0, "STATIC", "Radius", WS_CHILD | WS_VISIBLE | SS_RIGHT, 12, 267, 50, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndRadiusXValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_RIGHT | ES_AUTOHSCROLL, 66, 264, 80, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndRadiusXSpin = CreateWindowEx(0, UPDOWN_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_AUTOBUDDY, 126, 264, 20, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndRadiusYValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_RIGHT | ES_AUTOHSCROLL, 150, 264, 80, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndRadiusYSpin = CreateWindowEx(0, UPDOWN_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_AUTOBUDDY, 210, 264, 20, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndRadiusZValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_RIGHT | ES_AUTOHSCROLL, 234, 264, 80, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndRadiusZSpin = CreateWindowEx(0, UPDOWN_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_AUTOBUDDY, 294, 264, 20, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndFrustumX = CreateWindowEx(0, "STATIC", "X", WS_CHILD | WS_VISIBLE | SS_CENTER, 66, 302, 80, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndFrustumY = CreateWindowEx(0, "STATIC", "Y", WS_CHILD | WS_VISIBLE | SS_CENTER, 150, 302, 80, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndFrustumZ = CreateWindowEx(0, "STATIC", "Z", WS_CHILD | WS_VISIBLE | SS_CENTER, 234, 302, 80, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndFrustumMin = CreateWindowEx(0, "STATIC", "Minimum", WS_CHILD | WS_VISIBLE | SS_RIGHT, 12, 319, 50, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndFrustumMax = CreateWindowEx(0, "STATIC", "Maximum", WS_CHILD | WS_VISIBLE | SS_RIGHT, 12, 343, 50, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndXMinValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_RIGHT | ES_AUTOHSCROLL, 66, 316, 80, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndXMinSpin = CreateWindowEx(0, UPDOWN_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_AUTOBUDDY, 126, 316, 20, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndXMaxValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_RIGHT | ES_AUTOHSCROLL, 66, 340, 80, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndXMaxSpin = CreateWindowEx(0, UPDOWN_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_AUTOBUDDY, 126, 340, 20, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndYMinValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_RIGHT | ES_AUTOHSCROLL, 150, 316, 80, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndYMinSpin = CreateWindowEx(0, UPDOWN_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_AUTOBUDDY, 210, 316, 20, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndYMaxValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_RIGHT | ES_AUTOHSCROLL, 150, 340, 80, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndYMaxSpin = CreateWindowEx(0, UPDOWN_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_AUTOBUDDY, 210, 340, 20, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndZNearValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_RIGHT | ES_AUTOHSCROLL, 234, 316, 80, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndZNearSpin = CreateWindowEx(0, UPDOWN_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_AUTOBUDDY, 294, 316, 20, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndZFarValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_RIGHT | ES_AUTOHSCROLL, 234, 340, 80, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndZFarSpin = CreateWindowEx(0, UPDOWN_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_AUTOBUDDY, 294, 340, 20, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndCastShadows = CreateWindowEx(0, "BUTTON", "Cast shadows", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_AUTOCHECKBOX, 330, 94, 140, 16, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndShadowBias = CreateWindowEx(0, "STATIC", "Shadow bias", WS_CHILD | WS_VISIBLE | SS_RIGHT, 330, 119, 140, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndShadowBiasValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_RIGHT | ES_AUTOHSCROLL, 474, 116, 80, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndShadowBiasSpin = CreateWindowEx(0, UPDOWN_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_AUTOBUDDY, 534, 116, 20, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndShadowSlopeScaleBias = CreateWindowEx(0, "STATIC", "Shadow slope-scale bias", WS_CHILD | WS_VISIBLE | SS_RIGHT, 330, 143, 140, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndShadowSlopeScaleBiasValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_RIGHT | ES_AUTOHSCROLL, 474, 140, 80, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndShadowSlopeScaleBiasSpin = CreateWindowEx(0, UPDOWN_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_AUTOBUDDY, 534, 140, 20, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndShadowSoftness = CreateWindowEx(0, "STATIC", "Shadow softness", WS_CHILD | WS_VISIBLE | SS_RIGHT, 330, 167, 140, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndShadowSoftnessValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_RIGHT | ES_AUTOHSCROLL, 474, 164, 80, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndShadowSoftnessSpin = CreateWindowEx(0, UPDOWN_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_AUTOBUDDY, 534, 164, 20, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndFogDistance = CreateWindowEx(0, "STATIC", "Fog distance", WS_CHILD | WS_VISIBLE | SS_RIGHT, 330, 210, 140, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndFogDistanceValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_RIGHT | ES_AUTOHSCROLL, 474, 207, 80, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndFogDistanceSpin = CreateWindowEx(0, UPDOWN_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_AUTOBUDDY, 534, 207, 20, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndFogHeight = CreateWindowEx(0, "STATIC", "Fog height", WS_CHILD | WS_VISIBLE | SS_RIGHT, 330, 234, 140, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndFogHeightValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_RIGHT | ES_AUTOHSCROLL, 474, 231, 80, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndFogHeightSpin = CreateWindowEx(0, UPDOWN_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_AUTOBUDDY, 534, 231, 20, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndVolumeIntensity = CreateWindowEx(0, "STATIC", "Volumetric light intensity", WS_CHILD | WS_VISIBLE | SS_RIGHT, 330, 277, 140, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndVolumeIntensityValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_RIGHT | ES_AUTOHSCROLL, 474, 274, 80, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndVolumeIntensitySpin = CreateWindowEx(0, UPDOWN_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_AUTOBUDDY, 534, 274, 20, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndVolumeShadows = CreateWindowEx(0, "STATIC", "Volumetric light shadows", WS_CHILD | WS_VISIBLE | SS_RIGHT, 330, 302, 140, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndVolumeShadowsValue = CreateWindowEx(WS_EX_CLIENTEDGE, "COMBOBOX", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | CBS_DROPDOWNLIST, 474, 298, 80, 200, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndVolumeInteractions = CreateWindowEx(0, "STATIC", "Volumetric light interactions", WS_CHILD | WS_VISIBLE | SS_RIGHT, 330, 327, 140, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndVolumeInteractionsValue = CreateWindowEx(WS_EX_CLIENTEDGE, "COMBOBOX", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | CBS_DROPDOWNLIST, 474, 323, 80, 200, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndDetailLevel = CreateWindowEx(0, "STATIC", "Detail level", WS_CHILD | WS_VISIBLE | SS_RIGHT, 330, 370, 140, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndDetailLevelValue = CreateWindowEx(WS_EX_CLIENTEDGE, "COMBOBOX", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | CBS_DROPDOWNLIST, 474, 366, 80, 200, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndColor = CreateWindowEx(0, "STATIC", "Color", WS_CHILD | WS_VISIBLE | SS_RIGHT, 330, 411, 140, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndColorValue = CreateWindowEx(0, "BUTTON", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | BS_BITMAP, 474, 408, 80, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndAlpha = CreateWindowEx(0, "STATIC", "Alpha", WS_CHILD | WS_VISIBLE | SS_RIGHT, 330, 435, 140, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndAlphaValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_RIGHT | ES_AUTOHSCROLL, 474, 432, 80, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndAlphaSpin = CreateWindowEx(0, UPDOWN_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_AUTOBUDDY, 534, 432, 20, 20, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndMaterial = CreateWindowEx(0, "STATIC", "Material", WS_CHILD | WS_VISIBLE | SS_RIGHT, 12, 478, 134, 14, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndMaterialValue = CreateWindowEx(WS_EX_CLIENTEDGE, "COMBOBOX", NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP | CBS_DROPDOWN | CBS_SORT | CBS_AUTOHSCROLL, 150, 474, 404, 200, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndApply = CreateWindowEx(0, "BUTTON", "Apply", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON, 8, 523, 75, 23, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndReset = CreateWindowEx(0, "BUTTON", "Reset", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON, 87, 523, 75, 23, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndDefaults = CreateWindowEx(0, "BUTTON", "Defaults", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON, 166, 523, 75, 23, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndRemove = CreateWindowEx(0, "BUTTON", "Remove", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON, 245, 523, 75, 23, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);
	sg_lightParmsEditor.hWndSave = CreateWindowEx(0, "BUTTON", "Save", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON, 483, 523, 75, 23, sg_lightParmsEditor.hWnd, NULL, sg_lightParmsEditor.hInstance, NULL);

	// Create and set the font
	hDC = GetDC(sg_lightParmsEditor.hWnd);
	size = -MulDiv(8, GetDeviceCaps(hDC, LOGPIXELSY), 72);
	ReleaseDC(sg_lightParmsEditor.hWnd, hDC);

	sg_lightParmsEditor.hFont = CreateFont(size, 0, 0, 0, FW_LIGHT, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "Microsoft Sans Serif");

	SendMessage(sg_lightParmsEditor.hWndName, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndNameValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndBindTo, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndBindToValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndBindOrientated, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndFrame1, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndFrame2, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndFrame3, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndFrame4, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndX, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndY, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndZ, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndOrigin, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndOriginXValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndOriginYValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndOriginZValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndCenter, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndCenterXValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndCenterYValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndCenterZValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndAngles, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndAnglesXValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndAnglesYValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndAnglesZValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndStartOff, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndType, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndTypeValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndRadiusX, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndRadiusY, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndRadiusZ, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndRadius, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndRadiusXValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndRadiusYValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndRadiusZValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndFrustumX, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndFrustumY, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndFrustumZ, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndFrustumMin, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndFrustumMax, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndXMinValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndXMaxValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndYMinValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndYMaxValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndZNearValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndZFarValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndCastShadows, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndShadowBias, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndShadowBiasValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndShadowSlopeScaleBias, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndShadowSlopeScaleBiasValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndShadowSoftness, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndShadowSoftnessValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndFogDistance, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndFogDistanceValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndFogHeight, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndFogHeightValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndVolumeIntensity, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndVolumeIntensityValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndVolumeShadows, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndVolumeShadowsValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndVolumeInteractions, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndVolumeInteractionsValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndDetailLevel, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndDetailLevelValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndColor, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndAlpha, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndAlphaValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndMaterial, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndMaterialValue, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndApply, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndReset, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndDefaults, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndRemove, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);
	SendMessage(sg_lightParmsEditor.hWndSave, WM_SETFONT, (WPARAM)sg_lightParmsEditor.hFont, FALSE);

	// Create and set the bitmap
	sg_lightParmsEditor.hBitmap = CreateBitmap(80, 20, 1, 32, NULL);

	for (i = 0; i < LIGHT_COLOR_BITMAP_SIZE; i++)
		sg_lightParmsEditor.bitmapBits[i] = 0xFFFFFFFF;

	SetBitmapBits(sg_lightParmsEditor.hBitmap, LIGHT_COLOR_BITMAP_SIZE * 4, sg_lightParmsEditor.bitmapBits);
	SendMessage(sg_lightParmsEditor.hWndColorValue, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)sg_lightParmsEditor.hBitmap);

	// Fill bind-to combo box
	SendMessage(sg_lightParmsEditor.hWndBindToValue, CB_ADDSTRING, 0, (LPARAM)"");

	for (i = MAX_CLIENTS; i < level.numEntities; i++){
		if (!level.entities[i].inUse)
			continue;
		
		if (level.entities[i].state.type == ET_LIGHT)
			continue;

		SendMessage(sg_lightParmsEditor.hWndBindToValue, CB_ADDSTRING, 0, (LPARAM)level.entities[i].name);
	}

	// Fill type combo box
	SendMessage(sg_lightParmsEditor.hWndTypeValue, CB_ADDSTRING, 0, (LPARAM)"Point");
	SendMessage(sg_lightParmsEditor.hWndTypeValue, CB_ADDSTRING, 0, (LPARAM)"Cubic");
	SendMessage(sg_lightParmsEditor.hWndTypeValue, CB_ADDSTRING, 0, (LPARAM)"Projected");
	SendMessage(sg_lightParmsEditor.hWndTypeValue, CB_ADDSTRING, 0, (LPARAM)"Directional");

	// Fill volume shadows combo box
	SendMessage(sg_lightParmsEditor.hWndVolumeShadowsValue, CB_ADDSTRING, 0, (LPARAM)"Enabled");
	SendMessage(sg_lightParmsEditor.hWndVolumeShadowsValue, CB_ADDSTRING, 0, (LPARAM)"Disabled");

	// Fill volume interactions combo box
	SendMessage(sg_lightParmsEditor.hWndVolumeInteractionsValue, CB_ADDSTRING, 0, (LPARAM)"Enabled");
	SendMessage(sg_lightParmsEditor.hWndVolumeInteractionsValue, CB_ADDSTRING, 0, (LPARAM)"Disabled");

	// Fill detail level combo box
	SendMessage(sg_lightParmsEditor.hWndDetailLevelValue, CB_ADDSTRING, 0, (LPARAM)"Low");
	SendMessage(sg_lightParmsEditor.hWndDetailLevelValue, CB_ADDSTRING, 0, (LPARAM)"Medium");
	SendMessage(sg_lightParmsEditor.hWndDetailLevelValue, CB_ADDSTRING, 0, (LPARAM)"High");

	// Fill material combo box
	SendMessage(sg_lightParmsEditor.hWndMaterialValue, CB_ADDSTRING, 0, (LPARAM)"_defaultLight");
	SendMessage(sg_lightParmsEditor.hWndMaterialValue, CB_ADDSTRING, 0, (LPARAM)"_defaultProjectedLight");

	glqDefManager->EnumDefs(DEF_MATERIAL, SG_AddLightMaterial);

	// Set text limit for name edit box
	SendMessage(sg_lightParmsEditor.hWndNameValue, CB_LIMITTEXT, (WPARAM)(MAX_ENTITY_NAME_LENGTH - 1), 0);

	// Set text limit for material combo box
	SendMessage(sg_lightParmsEditor.hWndMaterialValue, CB_LIMITTEXT, (WPARAM)(MAX_PATH_LENGTH - 1), 0);

	// Set the current color
	sg_lightParmsEditor.crCurrent = RGB(255, 255, 255);

	// Set the custom colors
	for (i = 0; i < 16; i++)
		sg_lightParmsEditor.crCustom[i] = RGB(255, 255, 255);

	// Show the window
	ShowWindow(sg_lightParmsEditor.hWnd, SW_SHOW);
	UpdateWindow(sg_lightParmsEditor.hWnd);
	SetForegroundWindow(sg_lightParmsEditor.hWnd);
	SetFocus(sg_lightParmsEditor.hWnd);

	sg_lightParmsEditor.initialized = true;

	return sg_lightParmsEditor.hWnd;
}

/*
 ==================
 SG_DestroyLightEditorWindow
 ==================
*/
static void SG_DestroyLightEditorWindow (){

	if (!sg_lightParmsEditor.initialized)
		return;

	if (sg_lightParmsEditor.hBitmap)
		DeleteObject(sg_lightParmsEditor.hBitmap);

	if (sg_lightParmsEditor.hFont)
		DeleteObject(sg_lightParmsEditor.hFont);

	ShowWindow(sg_lightParmsEditor.hWnd, SW_HIDE);
	DestroyWindow(sg_lightParmsEditor.hWnd);

	UnregisterClass(LIGHT_EDITOR_WINDOW_CLASS, sg_lightParmsEditor.hInstance);

	glqMemory->Fill(&sg_lightParmsEditor, 0, sizeof(lightParmsEditor_t));
}

/*
 ==================
 SG_EditLightParameters
 ==================
*/
static void SG_EditLightParameters (int index, lightParms_t *parms){

	etEntity	*master;
	byte		r, g, b;
	int			i;

	if (!sg_lightParmsEditor.initialized)
		return;

	// Apply current light parameters
	SG_ApplyLightParameters();

	// Set the current light parameters
	if (parms){
		sg_lightParmsEditor.enabled = true;

		sg_lightParmsEditor.editIndex = index;
		sg_lightParmsEditor.editParms = *parms;
	}
	else {
		sg_lightParmsEditor.enabled = false;

		parms = &sg_lightParms;
	}

	// Update the controls
	SetWindowText(sg_lightParmsEditor.hWndNameValue, parms->name);

	index = SendMessage(sg_lightParmsEditor.hWndBindToValue, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)parms->bind);
	if (index == CB_ERR)
		SendMessage(sg_lightParmsEditor.hWndBindToValue, CB_SETCURSEL, (WPARAM)0, 0);
	else
		SendMessage(sg_lightParmsEditor.hWndBindToValue, CB_SETCURSEL, (WPARAM)index, 0);

	master = SG_FindEntity(parms->bind);

	if (parms->bindOrientated)
		SendMessage(sg_lightParmsEditor.hWndBindOrientated, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
	else
		SendMessage(sg_lightParmsEditor.hWndBindOrientated, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);

	SetWindowText(sg_lightParmsEditor.hWndOriginXValue, Str_FromFloat(parms->origin[0], -1));
	SetWindowText(sg_lightParmsEditor.hWndOriginYValue, Str_FromFloat(parms->origin[1], -1));
	SetWindowText(sg_lightParmsEditor.hWndOriginZValue, Str_FromFloat(parms->origin[2], -1));

	SetWindowText(sg_lightParmsEditor.hWndCenterXValue, Str_FromFloat(parms->center[0], -1));
	SetWindowText(sg_lightParmsEditor.hWndCenterYValue, Str_FromFloat(parms->center[1], -1));
	SetWindowText(sg_lightParmsEditor.hWndCenterZValue, Str_FromFloat(parms->center[2], -1));

	SetWindowText(sg_lightParmsEditor.hWndAnglesXValue, Str_FromFloat(parms->angles[0], -1));
	SetWindowText(sg_lightParmsEditor.hWndAnglesYValue, Str_FromFloat(parms->angles[1], -1));
	SetWindowText(sg_lightParmsEditor.hWndAnglesZValue, Str_FromFloat(parms->angles[2], -1));

	if (parms->flags & LIGHT_START_OFF)
		SendMessage(sg_lightParmsEditor.hWndStartOff, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
	else
		SendMessage(sg_lightParmsEditor.hWndStartOff, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);

	SendMessage(sg_lightParmsEditor.hWndTypeValue, CB_SETCURSEL, (WPARAM)glqMath::ClampInt(parms->type, 0, 3), 0);

	SetWindowText(sg_lightParmsEditor.hWndRadiusXValue, Str_FromFloat(parms->radius[0], -1));
	SetWindowText(sg_lightParmsEditor.hWndRadiusYValue, Str_FromFloat(parms->radius[1], -1));
	SetWindowText(sg_lightParmsEditor.hWndRadiusZValue, Str_FromFloat(parms->radius[2], -1));

	SetWindowText(sg_lightParmsEditor.hWndXMinValue, Str_FromFloat(parms->xMin, -1));
	SetWindowText(sg_lightParmsEditor.hWndXMaxValue, Str_FromFloat(parms->xMax, -1));

	SetWindowText(sg_lightParmsEditor.hWndYMinValue, Str_FromFloat(parms->yMin, -1));
	SetWindowText(sg_lightParmsEditor.hWndYMaxValue, Str_FromFloat(parms->yMax, -1));

	SetWindowText(sg_lightParmsEditor.hWndZNearValue, Str_FromFloat(parms->zNear, -1));
	SetWindowText(sg_lightParmsEditor.hWndZFarValue, Str_FromFloat(parms->zFar, -1));

	if (parms->noShadows)
		SendMessage(sg_lightParmsEditor.hWndCastShadows, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
	else
		SendMessage(sg_lightParmsEditor.hWndCastShadows, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);

	SetWindowText(sg_lightParmsEditor.hWndShadowBiasValue, Str_FromFloat(parms->shadowBias, -1));
	SetWindowText(sg_lightParmsEditor.hWndShadowSlopeScaleBiasValue, Str_FromFloat(parms->shadowSlopeScaleBias, -1));

	SetWindowText(sg_lightParmsEditor.hWndShadowSoftnessValue, Str_FromFloat(parms->shadowSoftness, -1));

	SetWindowText(sg_lightParmsEditor.hWndFogDistanceValue, Str_FromFloat(parms->fogDistance, -1));
	SetWindowText(sg_lightParmsEditor.hWndFogHeightValue, Str_FromFloat(parms->fogHeight, -1));

	SetWindowText(sg_lightParmsEditor.hWndVolumeIntensityValue, Str_FromFloat(parms->volumeIntensity, -1));

	SendMessage(sg_lightParmsEditor.hWndVolumeShadowsValue, CB_SETCURSEL, (WPARAM)(!parms->volumeShadows), 0);
	SendMessage(sg_lightParmsEditor.hWndVolumeInteractionsValue, CB_SETCURSEL, (WPARAM)(!parms->volumeInteractions), 0);

	SendMessage(sg_lightParmsEditor.hWndDetailLevelValue, CB_SETCURSEL, (WPARAM)glqMath::ClampInt(parms->detailLevel, 0, 2), 0);

	r = glqMath::FloatToByte(parms->color[0] * 255.0f);
	g = glqMath::FloatToByte(parms->color[1] * 255.0f);
	b = glqMath::FloatToByte(parms->color[2] * 255.0f);

	sg_lightParmsEditor.crCurrent = RGB(r, g, b);

	for (i = 0; i < LIGHT_COLOR_BITMAP_SIZE; i++)
		sg_lightParmsEditor.bitmapBits[i] = (b << 0) | (g << 8) | (r << 16) | (255 << 24);

	SetBitmapBits(sg_lightParmsEditor.hBitmap, LIGHT_COLOR_BITMAP_SIZE * 4, sg_lightParmsEditor.bitmapBits);
	SendMessage(sg_lightParmsEditor.hWndColorValue, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)sg_lightParmsEditor.hBitmap);

	SetWindowText(sg_lightParmsEditor.hWndAlphaValue, Str_FromFloat(glqMath::ClampFloat(parms->color[3], 0.0f, 1.0f), -1));

	SetWindowText(sg_lightParmsEditor.hWndMaterialValue, parms->material);

	// Enable or disable the controls
	EnableWindow(sg_lightParmsEditor.hWndName, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndNameValue, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndBindTo, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndBindToValue, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndBindOrientated, sg_lightParmsEditor.enabled && (master != NULL));
	EnableWindow(sg_lightParmsEditor.hWndFrame1, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndFrame2, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndFrame3, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndFrame4, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndX, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndY, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndZ, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndOrigin, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndOriginXValue, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndOriginXSpin, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndOriginYValue, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndOriginYSpin, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndOriginZValue, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndOriginZSpin, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndCenter, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndCenterXValue, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndCenterXSpin, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndCenterYValue, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndCenterYSpin, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndCenterZValue, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndCenterZSpin, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndAngles, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndAnglesXValue, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndAnglesXSpin, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndAnglesYValue, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndAnglesYSpin, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndAnglesZValue, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndAnglesZSpin, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndStartOff, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndType, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndTypeValue, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndRadiusX, sg_lightParmsEditor.enabled && parms->type != RL_PROJECTED);
	EnableWindow(sg_lightParmsEditor.hWndRadiusY, sg_lightParmsEditor.enabled && parms->type != RL_PROJECTED);
	EnableWindow(sg_lightParmsEditor.hWndRadiusZ, sg_lightParmsEditor.enabled && parms->type != RL_PROJECTED);
	EnableWindow(sg_lightParmsEditor.hWndRadius, sg_lightParmsEditor.enabled && parms->type != RL_PROJECTED);
	EnableWindow(sg_lightParmsEditor.hWndRadiusXValue, sg_lightParmsEditor.enabled && parms->type != RL_PROJECTED);
	EnableWindow(sg_lightParmsEditor.hWndRadiusXSpin, sg_lightParmsEditor.enabled && parms->type != RL_PROJECTED);
	EnableWindow(sg_lightParmsEditor.hWndRadiusYValue, sg_lightParmsEditor.enabled && parms->type != RL_PROJECTED);
	EnableWindow(sg_lightParmsEditor.hWndRadiusYSpin, sg_lightParmsEditor.enabled && parms->type != RL_PROJECTED);
	EnableWindow(sg_lightParmsEditor.hWndRadiusZValue, sg_lightParmsEditor.enabled && parms->type != RL_PROJECTED);
	EnableWindow(sg_lightParmsEditor.hWndRadiusZSpin, sg_lightParmsEditor.enabled && parms->type != RL_PROJECTED);
	EnableWindow(sg_lightParmsEditor.hWndFrustumX, sg_lightParmsEditor.enabled && parms->type == RL_PROJECTED);
	EnableWindow(sg_lightParmsEditor.hWndFrustumY, sg_lightParmsEditor.enabled && parms->type == RL_PROJECTED);
	EnableWindow(sg_lightParmsEditor.hWndFrustumZ, sg_lightParmsEditor.enabled && parms->type == RL_PROJECTED);
	EnableWindow(sg_lightParmsEditor.hWndFrustumMin, sg_lightParmsEditor.enabled && parms->type == RL_PROJECTED);
	EnableWindow(sg_lightParmsEditor.hWndFrustumMax, sg_lightParmsEditor.enabled && parms->type == RL_PROJECTED);
	EnableWindow(sg_lightParmsEditor.hWndXMinValue, sg_lightParmsEditor.enabled && parms->type == RL_PROJECTED);
	EnableWindow(sg_lightParmsEditor.hWndXMinSpin, sg_lightParmsEditor.enabled && parms->type == RL_PROJECTED);
	EnableWindow(sg_lightParmsEditor.hWndXMaxValue, sg_lightParmsEditor.enabled && parms->type == RL_PROJECTED);
	EnableWindow(sg_lightParmsEditor.hWndXMaxSpin, sg_lightParmsEditor.enabled && parms->type == RL_PROJECTED);
	EnableWindow(sg_lightParmsEditor.hWndYMinValue, sg_lightParmsEditor.enabled && parms->type == RL_PROJECTED);
	EnableWindow(sg_lightParmsEditor.hWndYMinSpin, sg_lightParmsEditor.enabled && parms->type == RL_PROJECTED);
	EnableWindow(sg_lightParmsEditor.hWndYMaxValue, sg_lightParmsEditor.enabled && parms->type == RL_PROJECTED);
	EnableWindow(sg_lightParmsEditor.hWndYMaxSpin, sg_lightParmsEditor.enabled && parms->type == RL_PROJECTED);
	EnableWindow(sg_lightParmsEditor.hWndZNearValue, sg_lightParmsEditor.enabled && parms->type == RL_PROJECTED);
	EnableWindow(sg_lightParmsEditor.hWndZNearSpin, sg_lightParmsEditor.enabled && parms->type == RL_PROJECTED);
	EnableWindow(sg_lightParmsEditor.hWndZFarValue, sg_lightParmsEditor.enabled && parms->type == RL_PROJECTED);
	EnableWindow(sg_lightParmsEditor.hWndZFarSpin, sg_lightParmsEditor.enabled && parms->type == RL_PROJECTED);
	EnableWindow(sg_lightParmsEditor.hWndCastShadows, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndShadowBias, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndShadowBiasValue, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndShadowBiasSpin, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndShadowSlopeScaleBias, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndShadowSlopeScaleBiasValue, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndShadowSlopeScaleBiasSpin, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndShadowSoftness, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndShadowSoftnessValue, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndShadowSoftnessSpin, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndFogDistance, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndFogDistanceValue, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndFogDistanceSpin, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndFogHeight, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndFogHeightValue, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndFogHeightSpin, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndVolumeIntensity, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndVolumeIntensityValue, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndVolumeIntensitySpin, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndVolumeShadows, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndVolumeShadowsValue, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndVolumeInteractions, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndVolumeInteractionsValue, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndDetailLevel, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndDetailLevelValue, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndColor, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndColorValue, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndAlpha, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndAlphaValue, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndAlphaSpin, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndMaterial, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndMaterialValue, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndApply, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndReset, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndDefaults, sg_lightParmsEditor.enabled);
	EnableWindow(sg_lightParmsEditor.hWndRemove, sg_lightParmsEditor.enabled);

	// Show the window
	ShowWindow(sg_lightParmsEditor.hWnd, SW_RESTORE);
	UpdateWindow(sg_lightParmsEditor.hWnd);
	SetForegroundWindow(sg_lightParmsEditor.hWnd);
	SetFocus(sg_lightParmsEditor.hWnd);
}

#else

/*
 ==================
 SG_CreateLightEditorWindow
 ==================
*/
static void *SG_CreateLightEditorWindow (){

	G_Printf(S_COLOR_RED "The light editor is not currently supported on this platform");

	return NULL;
}

/*
 ==================
 SG_DestroyLightEditorWindow
 ==================
*/
static void SG_DestroyLightEditorWindow (){

}

/*
 ==================
 SG_EditLightParameters
 ==================
*/
static void SG_EditLightParameters (int index, lightParms_t *parms){

}

#endif